对于产生大量短寿命垃圾且没有长寿命垃圾的应用程序而言,一种可行的方法是堆满一大堆东西,几乎所有年轻一代,几乎所有伊甸园和任职期都超过一个的YG集合。
例如(假设您有一个32位的jvm)
- 3072M堆(Xms和Xmn)
- 使用期限为128M(即Xmn 2944m)
- MaxTenuringThreshold = 1
- SurvivorRatio = 190(即每个幸存者空间是YG的1/192)
- TargetSurvivorRatio = 90(即尽可能地填充那些幸存者)
用于此设置的确切参数取决于您的工作集的稳态大小(即,每次收集时还剩下多少)。这里的想法显然违背了正常的堆大小调整规则,但是您没有一个具有这种行为的应用程序。这种想法是,该应用主要是短期垃圾和少量静态数据,因此请设置jvm,以使静态数据能够快速进入使用期,然后具有足够大的YG,以至于它不会经常被收集,从而将其最小化暂停的频率。您需要反复旋转旋钮才能确定适合您的尺寸,以及如何与每个系列的暂停尺寸相平衡。例如,您可能会发现更短但更频繁的YG暂停是可以实现的。
您没有说您的应用程序可以运行多长时间,但是这里的目标是在应用程序的生命周期内完全没有永久性集合。当然这可能是不可能的,但值得针对。
但是,在您的情况下,不仅重要的是收集算法,还分配了内存。NUMA收集器(仅与吞吐量收集器兼容并由UseNUMA开关激活)利用了这样的观察:对象通常仅由创建该对象的线程使用,从而相应地分配内存。我不确定它在Linux中基于什么,但是它在Solaris上使用MPO(内存放置优化),有关GC博客之一的一些详细信息
由于您使用的是64位jvm,因此请确保同时使用CompressedOops。
给定对象分配的速率(可能是某种科学的自由吗?)和生存期,那么您应该考虑对象重用。lib的一个示例就是javalution StackContext
最后值得一提的是,GC暂停不是唯一的STW暂停,您可以使用6u21抢先体验版本运行,该版本对PrintGCApplicationStoppedTime和PrintGCApplicationConcurrentTime开关(在全局安全点和这些安全点之间的时间有效打印时间)进行了一些修复。您可以使用tracesafepointstatistics标志来了解导致它需要安全点的原因(也就是任何线程都没有执行字节码)。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)