【发布时间】:2012-08-05 22:09:40
【问题描述】:
我正在分析一个 java 功能测试,该测试需要很长时间并且偶尔会出现 OOM(在 C 堆中,而不是 java 中),我发现 java 串行 GC 中的行为非常次优(它可能适用于所有 java GC。)
以下是测试运行中完整 GC 点的 Permgen 统计数据示例(大小以 KB 为单位):
before after commit
167935 167935 167936
172031 172031 172032
如您所见,这些完整的 gc 运行并未清理 permgen 空间。没什么大不了的,但它表明这些完整的 gc 是无用的。此外,提交值有点有趣。我假设 gc 日志条目的提交值将是提交大小增加后的值。我现在认为它实际上是完整 GC 运行之前的提交值。
此外,我认为 permgen 提交的大小在每次完整 GC 运行时以 4MB (172032K - 167936K) 的固定、不可调整的大小增长。这意味着如果您从默认的 permgen 大小开始,例如 64mb,当您的应用程序完全启动时,它需要 128mb 的 permgen,那么 permgen 需要 16 个完整的 gc 才能达到其最终提交大小。
在我正在分析的功能测试的情况下,必须运行 58 个完整的 gc,每个需要 0.5 到 2 秒。通过使 jvm 参数 -XX:PermSize 等于 -XX:MaxPermSize 我能够将其减少到零完整 GC(不会显着增加更快的新一代 gc)并减少 gc 检测报告的 GC 时间消息减少 90%,从 90 秒到 9 秒。
我查看了很多地方,但找不到用于 permgen 堆的提交大小增长率的不同调整参数。在程序启动时完全分配 permgen 堆的最大可能大小有点难看。有谁知道将 PermSize 增加到等于 MaxPermSize 的替代方法,它可以在启动时不分配这么多内存的情况下获得类似的结果?为什么 permgen 提交增量如此之小且固定?
【问题讨论】:
标签: java garbage-collection jvm permgen