当前位置:首页 > 内存 > 正文

java进程占用内存远大于dump

  • 内存
  • 2024-08-22 16:31:09
  • 9509

一、java内存dump文件怎么定位到具体的线程1.首先您需要创建一个内存转储文件。使用Java虚拟机附带的jmap工具创建内存转储文件。
2。然后,使用内存分析工具打开转储文件。内存转储文件无法直接读取。您可以使用EclipseMAT和VisualVM等内存分析工具来打开它。
3。最后确定具体字符串的位置。在内存分析工具中,会有一个“Threads”和“Threads”选项卡。此选项卡可以查看所有字符串,以便您可以找到特定字符串。


二、记一次FGC事件和解决

一次探索和修复服务器故障的经历


早上进入办公室,我平静的日常生活被一封电子邮件服务器警报、界面异常打断了。我立即专心追踪问题,直奔问题根源——Java进程的CPU使用率呈爆炸式增长,服务陷入停滞。


问题诊断


首先,我登录到服务器(CentOS7)并使用了主要工具,并在找到罪魁祸首正是Java进程,其CPU占用率高达100%,严重阻碍了后续服务的正常运行。接下来我调整了负载均衡策略,将有问题的服务器从集群中移除,以缓解压力。


接下来,我们通过jps命令发现Tomcat进程PID异常,假设为10086。进一步使用jstat-gcutil进行内存使用分析,发现了问题的关键问题:新生代使用ParNew收集器,而老年代使用CMS收集器,但是InitiatingOccupancyFraction设置为80%,这意味着一旦老年代的利用率达到80%以上,就会触发频繁的FGC(FullGarbageCollection),这显然加剧了服务的不稳定。


深入问题的根源


使用jmap-histo检查内存泄漏的迹象,导致大量的实例引起了我的注意。在查看代码时,我发现可能是由于频繁上传和下载图片导致的。然而,凭这一点并不能得出结论,因此我决定获取更详细的内存状态。


通过jmap-dump,我获取了一个缓存文件并将其导入到Eclipse的MAT工具中进行深入分析。结果暴露了一个令人烦恼的问题:名为IdleConnectionReaper的守护线程中的ArrayList内存太大,导致内存泄漏。该类负责管理上传和下载线程,但是默认的连接数非常大,导致内存消耗非常快。


问题定位及解决


深入研究了该类相关的代码和资料,发现了核心问题描述:代码为每次上传或下载操作创建一个新的OSSClient实例,由于过多的创建和销毁操作而积累了系统资源。为了解决这个问题,我修改了代码,使用单例模式来管理OSSClient,减少了资源浪费。经在线核实,问题得到缓解,服务稳定。


经验总结


这次经历让我深刻体会到在处理大规模需求时,我们必须注意内存消耗,合理使用合并技术,降低系统创建和销毁对象的总体成本。此外,CMS收集器的CPU占用率高、无法处理浮动垃圾、内存碎片等缺点也需要我们关注。通过调整UseCMSCompactAtFullCollection和CMSFullGCsBeforeCompaction参数,可以优化FGC策略,提高内存使用效率,保证服务稳定运行。