我开发了一个处理大量数据并需要花费大量时间才能完成的Web应用程序?
所以现在我正在对我的应用进行分析,我注意到GC的一个非常糟糕的事情
当全GC发生时,它会停止所有过程30-40秒。
我想知道是否有办法改善这一点。我不想只在GC中占用我的CPU那么多时间。以下是一些有用的细节:
答案 0 :(得分:5)
现代JVM用于垃圾收集的算法很多。诸如引用计数之类的一些算法如此之快,并且诸如存储器复制之类的一些算法如此之慢。您可以更改代码,以便在大多数情况下帮助JVM使用更快的算法。
最快的算法之一是引用计数,正如名称所描述的,它计算对象的引用,当它达到零时,它就可以进行垃圾收集,之后它会减少对引用的对象的引用计数。当前的GCed对象。
为了帮助JVM使用这个算法,避免使用循环引用(对象A引用B,然后B引用C,C引用D ....,Z再次引用A)。因为即使整个对象图不可访问,对象的引用计数器也都不会达到零。
当您不再需要圆圈中的对象时(通过将null指定给引用之一),您只能打破圆圈....
答案 1 :(得分:4)
如果您使用64位架构添加:
-XX:+UseCompressedOops
64位地址转换为32位
使用G1GC代替CMS:
-XX:+UseG1GC
- 它使用增量步骤
设置相同的初始和最大尺寸:-Xms5g -Xmx5g
调整参数(仅举例):
-XX:MaxGCPauseMillis=100 -XX:GCPauseIntervalMillis=1000
请参阅Java HotSpot VM Options 效果选项
答案 2 :(得分:4)
通过重复使用资源来改进应用,或者在应用的某些关键区域(无法保证帮助您)自己System.gc()
。很可能你有一个内存泄漏,你必须调查,然后重组代码。
答案 3 :(得分:3)
在GC中花费的时间取决于两个因素:
finalize()
无法访问且不使用finalize()
的对象无需花费任何费用来清理Java,这就是为什么Java通常与其他语言(如C ++)相同(并且通常更好,因为C ++花费了很多时候删除对象。)
因此,您需要在应用程序中执行的操作将减少代码中较早的对象数量和/或剪切对象(您不再需要的对象)的引用。例如:
当你有一个很长的方法时,你将保留所有从局部变量引用的对象。如果在许多较小的方法中拆分该方法,则引用将更快地丢失,并且GC将不必处理这些对象。
如果您在巨大的哈希映射中放置了您可能需要的所有内容,那么映射将使所有这些实例保持活动状态,直到代码完成为止。所以即使你不再需要它们,GC仍然需要花时间在它们上面。
答案 4 :(得分:3)
您new
的内容越少,需要收集的内容就越少。
假设你有A班。
您可以在其中包含对A类的另一个实例的引用。
这样你就可以制作一个A的实例的“免费列表”。
每当你需要一个A时,只需从免费列表中弹出一个。
如果空闲列表为空,则new
一个。
当您不再需要它时,将其推到空闲列表中。
这可以节省很多时间。