所以,开玩笑的是,我公司的一个应用程序版本最近遇到了一些内存问题,我并不完全确定解决它的最佳方法并非只是&# 34;分配更多内存",所以我想获得一些指导。
对于应用程序来说,当eden堆有并发用户时,它看起来很快就会变得非常快,所以很久没有活动的对象会在旧堆中结束。运行一段时间之后,旧堆只会变满,并且似乎永远不会自动清理,但在VisualVM中手动运行垃圾收集会清除它(所以我认为这意味着旧堆充满了死对象)
是否有任何建议我可以添加,所以垃圾收集一旦达到某个阈值就会在旧堆上运行?将旧/爱丁比从2: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空间全天运行,甚至不需要进行小型收集。