当前位置: 首页 > 知识库问答 >
问题:

Java-GC正在运行,但不回收任何东西

周兴朝
2023-03-14

在过去的几天里,我们看到服务器上的JVM进入了一种状态,他们在OldGen的GC中花费了100%的CPU时间,当时:

答:他们不需要这样做,因为堆上还有足够的空间

B.他们没有回收任何东西。

通过查看堆栈跟踪并将ProcessExplorer中的ThreadID与堆栈转储中的ThreadID关联,我知道它们在GC中。每个GC线程占用大约4%的CPU。

服务器运行16 gig堆(32gig物理RAM)

这是Duration的图表,时间尺度=19天。http://i45.tinypic.com/257qalu.png

这是图表尾部的放大图http://i48.tinypic.com/2duiccw.png

正如你所见,持续时间急剧增加。

下面是GC之后堆使用情况的图表。http://i48.tinypic.com/znna4h.png

如果这是一个典型的内存泄漏,我希望看到橙色的峰值越来越高,直到它们不能再达到峰值,但正如这张图所示,还有大量的堆空间。

我为每个服务器都有堆转储,没有什么问题。有一些ehCache存储,我可以看到我们的应用程序代码,即只是“普通的东西”

我们在大约20天前做的最大改变是实现了一个供应商补丁,该补丁将内部缓存从使用硬引用(以及明显的内存泄漏)的无界哈希映射更改为包含软引用的缓存

有人知道下一步该去哪里吗,或者有人能证实我的软参考理论吗?

这是我的jvm。args:

350m=-server-Xms16000m-Xmx16000m-Dsun.io.useCanonCache=false-XX: MaxPermSize=java.args-Xloggc: e:/gcLogs/eRGCLogs.txt-详细: gc-XX: PrintGCTimeStamps-XX: PrintGCDateStamps-XX: UseParallelGC-XX: UseParallelOldGC-Dnet.sf.ehcache.sizeof.filter=D:/jo3/java_ehCacheOpenSource/sizeOfExclusions.config-Xbat-Dcoldfusion.rootDir={application.home}/.../-Dcoldfusion.libPath={application.home}/.../lib-Dcoldfusion.classPath={application.home}/.../lib/更新,{application.home}/.../lib,{application.home}/.../网关/lib/,{}application.home/.../www root/WEB-INF/flex/jars,{application.home}/.../www root/WEB-INF/cfform/jars, d:/jo3/java, d:/JO3/java_ehCacheOpenSource

我们在ColdFusion上,这有点像一个位于java之上的大型框架。

JVM版本: 1.6.0_29

根据要求,“正常”GC日志如下所示:

2013-03-19T22:11:36.670 1100: 1288665.702:[GC[PSYoungGen:4695800K-

当我们处于故障模式时,GC日志如下所示:

2013-03-22T10:03:47.619 1100:1504185.901[GC[PSYoungGen:0K]-

共有1个答案

苏建安
2023-03-14

正如许多人在评论中提到的,PermGen中的空间不足很可能是您的原因。这可能是由于在整个代码中过度插入字符串造成的,这可能导致PermGen“爆炸”——也加载了很多类(通常是通过在后台为您执行此操作的框架)也可能导致这种情况。

此外,正如其中一条评论所提到的,使用CMS系列(并发标记和扫描)可以减少全球地面军事系统的停机时间,前提是问题在于老一代的容量。它还可以通过减少延迟来提高性能,无论当前的问题如何,延迟都是好的。

此外,如果您发布GC日志的片段,这将有助于为您指明正确的方向。

关于jstat工具,您可以通过以下方式使用它来获得有用的信息:

jstat -gcutil <pid> <interval> 

我通常使用1000毫秒的间隔<代码>-gcutil为您提供GC利用率(单位为%)——因此您可以查看是否有任何一代正在接近100%。

您也可以使用jstat-gc

编辑:审查GC日志后

根据你的GC日志,它确认了你的PermGen正在填充的原始前提。在10:03:47和10:03:55之间的时间范围内,我可以看到PermGen不断达到最大值,然后GC以某种方式删除了大约10-100KB的数据:

请参阅以下内容:

2013-03-22T10:03:47.631+1100: 1504185.912: [Full GC [... [PSPermGen: 358399K->358278K(358400K)]...
2013-03-22T10:03:53.175+1100: 1504191.456: [Full GC [... [PSPermGen: 358399K->358371K(358400K)]...
2013-03-22T10:03:55.802+1100: 1504194.082: [Full GC [... [PSPermGen: 358399K->358389K(358400K)]...

如果你看看老一代和年轻一代,你会发现他们都没有达到最大值,老一代消耗了10GB中的4GB——所以这不是原因。

从您收集的数据来看,我无法判断PermGen的填充速度是否与过程的填充时间一致——这意味着PermGen应该在一天内填充,而不是20天。所以很难说什么是明确的解决方案,但这里有一些建议:

  1. 检查您的代码以确保您没有滥用Stringintern()方法-如果您无缘无故地在代码中使用它太广泛,这可能是您的根本原因。
  2. 检查您使用的框架是否动态生成类-这也会消耗PermGen空间,但在一定程度上。
  3. 如果可以,每周重新启动您的进程以防止这种停机时间
  4. 考虑增加PermGen空间,但要对其进行监控,因为增加它可能只会延长您的20天周期,但不能解决问题。在流程存在足够长的时间后,PermGen应该保持相当静态。
  5. 使用字符串ColdFusion PermGen在Google上进行搜索会产生许多报告问题的点击-尝试关注这些问题以使您专注于您的调查。

 类似资料:
  • 问题内容: 几天前,我尝试创建一个服务器- 客户端或客户端服务器,作为实验来学习使用线程的套接字,但后来有人告诉我应该使用swingWorker。我研究了如何使用它,并在实践中实现了它,但是它仍然不起作用。即使我获得连接并使用了.excute(),swingWorker线程也似乎没有运行。如果你们能帮我找出我做错的地方,那将是很好的。SwingWorker类位于startSever()和start

  • 我试图解决Leetcode上的二和算法: 给定一个整数数组,返回两个数字的索引,使它们相加到一个特定的目标。您可以假设每个输入都有一个解决方案,并且不能两次使用同一个元素。 我想到了这个: 问题是它没有返回任何内容,也没有返回打印的声明。有什么想法吗?

  • 问题内容: 我有以下代码: 该文件包含以下内容: 但是由于某种原因,每次都只返回一个空列表。 代码中可能存在愚蠢的错误或错字,但我只是找不到。提前致谢。 问题答案: 你读的文件 已经 和文件指针不是在 末尾 的文件。然后调用将不会返回数据。 仅读取一次文件: 另一种选择是在重新阅读之前先回到开头: 但这只是浪费CPU和I / O时间。 最好的办法是尝试和阅读 小 数据量,或寻求到了最后,通过采取文

  • 我正在尝试创建计划任务以运行批处理文件。我知道我的批处理文件运行良好,因为手动运行它没有问题。但是,当任务调用它时,它会说它正在运行,但它不是。我知道它没有运行的原因是它调用了一个python脚本,python脚本发送了一封电子邮件,告诉我进程已经开始了。我没有收到那封电子邮件。python进程不会花费太长的时间(最多5分钟),而且任务一直说它在一小时后“运行”。 我有当前设置与运行用户是否登录或

  • Tracing References # gc_get_referents.py import gc import pprint class Graph: def __init__(self, name): self.name = name self.next = None def set_next(self, next):

  • 问题内容: 我正在尝试将.csv文件中的大量数据转储到SQL Server 2012数据库中。我没有进行数千次INSERT的工作,而是在进行调查。 编辑: 这是一个自动化的过程,而不是一次性的。我也没有此数据库的权限。 当我尝试将数据复制到数据库中时,不会返回任何错误,但实际上也不会复制任何内容-它只会返回。我已将其缩减为无法正常工作的最小情况。 首先,创建一个包含两列的简单表: 然后,使用来从中