提取一个堆转储,我意识到它有许多对象等待完成,其中大多数是来自库的实例,如jdbc连接等。
知道队列中的那些实例基本上都是实现finalize()的类,为什么它们不能被最终确定呢?
几天前,我回忆起了这样的例子。最初它有1 MB,新一代设置为256MB (-Xmx1g -XX:NewSize=256m -XX:MaxNewSize=256m)。随着我们添加了一些繁重的缓存功能,我们将分配给该实例的内存提高到3 GB (-Xmx3G -XX:NewSize=512m -XX:MaxNewSize=512m)。从那一刻起,我们开始看到一些记忆之外的东西。调查了一下,我发现了很多等待完成的java.lang.ref.Finalizer和对象。
这怎么可能相互关联呢?它甚至可能是相关的吗?
发布于 2016-09-30 19:56:16
为什么它们不会被最终确定呢?
有些组件需要更长的时间才能完成,尤其是涉及IO的任何事情。JDBC连接是相对较重的网络资源,因此它们需要更长的时间。
我建议您使用连接池(大多数JDBC库都内置了连接池),这样您就不会一直创建/销毁它们。
注意:为了澄清1Gb =1千兆位或128MB(兆字节),256 mb是256毫位或大约1/4位。-XX:NewSize=512m是512MB而不是256MB。-XX:MaxNewSize=512不能工作,因为它只有512字节,很可能您使用的是-XX:MaxNewSize=512m
3Gb是3千兆位的,但假设你的意思是3 Gb,它不是-Xmx1G,它是1 GB或8 GB。
发布于 2016-09-30 20:38:16
垃圾收集器在清理的最后一步调用Object.finalize()。GC定期运行(取决于您使用的GC,如果是7和8,它可能是CMS,或者如果您配置了G1,则可能是CMS)。拥有大量处于“等待完成”状态的对象可能意味着你有一个很大的堆和足够的内存,GC不需要运行(很可能是CMS,因为G1运行微清理的频率要高得多)。
将GC跟踪添加到您的JVM启动参数并监视其运行频率:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps请参阅:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html
如果你正在使用大量堆大于1 1Gb的小对象,你可能会考虑使用G1垃圾收集器,因为它更适合于这样的任务,并且没有内容管理系统的“停止世界”行为。
https://stackoverflow.com/questions/39790902
复制相似问题