JVM垃圾收集和分页内存架构

Kar*_*rlP 17 java garbage-collection

在讨论java和/或垃圾收集的最近10年中,我无法防范的唯一性能损失是垃圾收集算法在分页内存架构中运行时或多或少会中断,并且堆的部分内容正在变得越来越多分页.

Unix系统(尤其是Linux)积极地记录了一段时间没有被触及的内存,虽然这对于你的普通泄漏应用程序来说是好的,但它会在内存紧张的情况下杀死javas性能.

我知道最好的做法是保持最大堆小于物理内存.(或者你会看到你的应用程序交换死亡)但是这个想法 - 至少在unix世界中,是内存可以更好地用于文件系统缓存等.

我的问题是:是否有任何分页(识别)垃圾收集算法?

kdg*_*ory 9

我要争辩说,这不像你想象的那么大.

为了确保我们描述相同的事情:完整的集合需要JVM遍历对象图以识别每个可到达的对象; 留下的是垃圾.这样做时,它将触及应用程序堆中的每个页面,这将导致每个页面在被换出时出现故障.

我认为这是一个无关紧要的原因有以下几点:首先,因为现代JVM使用世代收藏家,而且大多数物体永远不会走出年轻一代,几乎可以保证它们在常驻集中.

其次,因为移出年轻一代的物体仍然经常被访问,这再次意味着它们应该在常驻集中.这是一个更为脆弱的论点,实际上有很多情况下,除了GC之外,长期存在的对象不会被触及(我不相信内存限制的缓存的一个原因).

第三个原因(可能还有更多)是因为JVM(至少是Sun JVM)使用了mark-sweep-compact收集器.因此,在GC之后,堆中的活动对象占用的页数较少,再次增加了RSS.顺便提一下,这是Swing应用程序在最小化时显式调用System.gc()的主要驱动因素:通过压缩堆,当它们再次最大化时,交换的次数较少.


此外,认识到C/C++对象的堆碎片可能会变得极端,而年轻的对象将会被淘汰,因此RSS必须更大.


小智 5

你是对的,垃圾收集器和虚拟内存管理器必须协作,否则GC会废弃系统.Matthew Hertz,Yi Feng和Emery D. Berger对此类GC /内核协作进行了调查.为了获得良好的性能,他们不得不稍微扩展内核并调整垃圾收集器.

在高内存压力下,使用GenMS Java GC,他们的基准测试时间缩短了160倍.使用新的页面感知GC,基准测试只慢了1.6倍.换句话说,通过适当调整的GC,可获得100倍的性能提升.

http://lambda-the-ultimate.org/node/2391