需要有关转动Java垃圾收集的建议

时间:2015-07-23 03:56:45

标签: java garbage-collection

所以,开玩笑的是,我公司的一个应用程序版本最近遇到了一些内存问题,我并不完全确定解决它的最佳方法并非只是&# 34;分配更多内存",所以我想获得一些指导。

对于应用程序来说,当eden堆有并发用户时,它看起来很快就会变得非常快,所以很久没有活动的对象会在旧堆中结束。运行一段时间之后,旧堆只会变满,并且似乎永远不会自动清理,但在VisualVM中手动运行垃圾收集会清除它(所以我认为这意味着旧堆充满了死对象)

是否有任何建议我可以添加,所以垃圾收集一旦达到某个阈值就会在旧堆上运行?将旧/爱丁比从2:1改为1:1是否有任何陷阱?对于应用程序,创建的大多数对象是我认为短暂的(从几毫秒到几分钟)

1 个答案:

答案 0 :(得分:1)

  

当eden堆有并发用户时,它看起来很快就会变得很快,所以很久没有活着的对象会在旧堆中结束。

这称为"过早推广"

  

运行一段时间后,旧堆只会变满,

当它填满时,GC会触发一个主要甚至是完整的集合。

  

似乎永远不会自动清理

在这种情况下,它既可以使用,也可以不完全填满。它可能看起来几乎已满,但GC将在它实际已满时执行。

  

但在VisualVM中手动运行垃圾收集将清除它

所以老一代几乎没有实际上已经满了。

  

我可以添加垃圾收集一旦达到某个阈值就会在旧堆上运行吗?

您可以运行System.gc(),但这意味着您可以为您的应用程序做更多的工作并减慢它的速度。你不想这样做。

如果您使用CMS收集器,您可以更改其启动的阈值,但除非您需要低延迟,否则最好不要将设置保留原样。

  

将旧/爱丁比从2:1改为1:1是否存在任何陷阱?

你可以减少旧版本,你可以减少你所执行的GC数量的一半,并且可以将对象可以存活的时间加倍,而不是在旧版本中结束。

我在低延迟空间工作,通常将年轻空间设置为24 GB,旧设置为2 GB。我还使用了大量的堆外数据,因此我不需要太多的旧数据。这不是一般的用例,但它可以根据您的要求工作。

如果您正在使用< 32 GB,只需添加几个GB可能是最简单的答案。您也可以使用-Xmn4g -Xms6g之类的东西来设置年轻空间和最大堆,而不用担心比率。

  

对于应用程序,创建的大多数对象都是我认为短暂的(从几毫秒到几分钟)

在这种情况下,理想情况下,您希望您的伊甸园空间足够大,以便每隔几分钟就有一个小集合。这样,大多数物体都会在伊甸园空间中死亡,而不会被复制。

注意:在极端情况下,应用程序每小时可以生成少于1 GB的垃圾,并且可以使用24 GB Eden空间全天运行,甚至不需要进行小型收集。