java - 为什么 PermGen Commit 增量这么小?

标签 java garbage-collection jvm permgen

我正在分析一个 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,它需要 16 个完整的 gc 才能使 permgen 达到其最终提交大小。

在我分析的功能测试中,必须运行 58 次完整的 gc,每次需要 0.5 到 2 秒。通过使 jvm 参数 -XX:PermSize 等于 -XX:MaxPermSize 我能够将其减少到零完整 GC(不会显着增加更快的新一代 gc)并减少 gc 检测报告的 GC 时间消息减少 90%,从 90 秒减少到 9 秒。

我看了很多地方,但找不到针对 permgen 堆的提交大小增长率的不同调整参数。在程序启动时完全分配 permgen 堆的最大可能大小有点丑陋。有谁知道将 PermSize 增加到等于 MaxPermSize 的替代方法可以在启动时不分配那么多内存的情况下获得类似的结果?为什么 permgen 提交增量这么小而且固定?

最佳答案

Permgen 不会被垃圾回收。 (在正常情况下)。 Permgen 是保存实际类对象和 Java 运行时的其他“内容”的地方。当您的应用程序初始化和使用各种类和/或加载和/或使用 jar 时,那些关联的类文件基本上存储在 permgen 中。

必须有其他与您的应用特别相关的相关参数才能解释您的观察结果。

permgen 增加和垃圾收集之间确实没有记录在案的关系。 Permgen 用于存储 jvm 使用的 static 数据,通常 不会被收集(除非在极少数情况下,即 ClassLoader 加载类,然后说 ClassLoader 超出范围)

关于java - 为什么 PermGen Commit 增量这么小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11870622/

相关文章:

java - 如何加快我的 Java 游戏的 FPS?

java - 如何处理提交JSP表单时的Servlet程序

java - 多个虚拟机的垃圾收集

java - 接近空的 Java For-Loop 行为异常

java - Kotlin-Java 互操作不适用于可变参数

java - 如何高效地 dockerized java 微服务

java - Spring 中的超时 session

JavaFx:显示日期选择器

java - 我们可以在 java 中实现的性能改进功能列表

Java 8 full GC 和 OutOfMemory Java 堆空间