安全相关的分析
在前面的问题分析和总结中,我们已经提到了出现该问题一种很大的可能是和补丁的升级和安装有关系,因此在对内存Dump文件的类追踪树进行追踪的时候经常会看到Security相关的字样,类似java.security.accesscontrolcontext这个类。
那么是否有可能是我们在升级了安全补丁后,出于安全方面的要求,在应用程序装载完成后需要对相关的目录进行安全扫描,但是我们的这个control临时文件目录和临时文件太大,导致了扫描和装载的时候出现了内存溢出。
因此昨天我又对我们升级的几个补丁进行了排查,基本的一个思路是我们在dump文件中能够查询到和安全相关的反复出现的几个关键类,然后通过这些关键字在补丁包的jar包文件和class文件中对这些关键字进行搜索,但是经过分析和比对暂时没有发现更多的信息。
回到对源代码的分析上
在前面一篇文章分析中,我们已经谈到通过fileList这个关键字入口找到了一些关键信息。但是在对dump文件中的Thread-0线程分析中,我们看到了如下线索,即:
1. 首先能够明确的看到,通过相关代码拼装和找到MFT的文件存储路径
2. 在找到文件存储路径后,在文件实例化之前,有装载目录操作,即装载目录后才是列出目录文件
因此我们关键点回到是否能够在代码里面找到这些操作的关键源代码,我们最开始的发起是用dump文件里面发现的mft.storage关键字进行搜索,在搜索中找到的具体有用信息如下:
mft.storage搜索的时候
->MetaDataServiceImpl.resetMetadata方法
->PurgeMDSService.resetToSeeded方法
->SeedGenerator.seedAll方法
->seedAppSettings方法
->appProperty.setStorageDirectory("$DOMAIN_HOME/mft/storage");
MFTUtil.getInstance().getStorageLocationDir方法
->JCABindingListenerImpl.processMessage方法
->JMSBindingListenerImpl.post方法
TaskQueueTaskType.onMessage方法
->getStorageLocationDir方法
FSArchiveService.archiveBatchOfPayloads方法
->getStorageDirectory方法
purge方法入口
->FSPurgeService.purgeBatchOfPayloads方法
->getStorageDirectory方法
通过上面的代码追溯,基本能看到
1. MetaDataServiceImpl 和 RuntimeServiceMXBeanImpl 是两个核心实现类
2. 获取目录最终还是追溯回了purgeBatchOfPayloads和archiveBatchOfPayloads两个方法
通过purge方法可以追溯到executePurge方法,而发起这个方法调用点有两个
1. handleRuntimePurgeExecution方法
2. onScheduleExpiry方法
对于onScheduleExpiry在前面一篇文章已经做过分析,另外一个方法如下:
handleRuntimePurgeExecution方法
->RuntimePurgeService.getInstance().purgeInternal
01->purgeInstanceData
->后续追溯线索断掉
02->executePurgeSchedule
->onScheduleExpiry方法
也就是经过进一步的追溯我们仍然是回到了上一篇文章的分析点,暂时没有新的发现。对于当前的一个关键疑问没有解决的还是如下:
即如何通过内存dump数据的MAT分析能够发现一个 Thread线性究竟是如何启动的,在哪里启动?如果谁在这方面有经验,也欢迎提供进一步的分析方法。
近期的gc内存日志数据监控
在我们对临时目录和临时文件进行删除的同时,我们对集群所有节点的内存gc数据日志进行了监控,从最近几天的监控情况可以看到,基本没有触发过大的full gc操作。其次,对于cms gc操作基本上每次只需要执行1次即可以将堆内存回收下来。
如果是当前这个日志数据来看,基本就已经到了一个正常的水平。
对于堆内存的持续缓慢增长本身并不是什么问题,关键还是不要有内存泄漏或者说长时间的内存无法释放,那么在内存增长到堆内存的80%(我们当前设置的阈值是80%)的时候就会触发cms gc操作进行内存回收。在内存回收的时候只要内存能够正常回收下来基本就可以算做是问题解决。
当前唯一还没有查找到明确结论的点还是在于究竟是什么启动了Thread-0线程对临时目录进行了大量的扫描,然后在扫描完临时目录后还对临时文件进行了大量的实例化操作导致了大量的内存占用。因此对于该问题点仍然会作为一个遗留问题点持续跟踪。