javaw 进程的私有字节数增加 java 8
private bytes increase for a javaw process in java 8
我的项目已经开始使用 java 8 来自 java 7。
切换到 java 8 后,我们发现内存消耗随时间增加等问题。
以下是我们所做的调查:
- 只有从 java7 和 java8
迁移后才会出现问题
- 因为元空间是唯一与内存相关的东西,它从 hava 7 更改为 java8。我们监控了元空间,它不会增长超过 20 MB。
- 堆也保持一致。
现在剩下的唯一途径就是分析内存如何分配给 java 7 和 java 8 中的进程,特别是私有字节内存。如有任何想法或链接,我们将不胜感激。
注意:此 javaw 应用程序是基于 swing 的应用程序。
更新 1:使用 NMT 工具分析本机内存并生成与基线相比的内存占用差异。我们发现堆保持不变,但 线程正在泄漏所有这些内存。因此,由于堆没有变化,我假设此泄漏是由于本机代码造成的。
所以挑战仍然开放。关于如何分析所有线程占用的内存的任何想法在这里都会有所帮助。
以下是从本机内存跟踪中获取的快照。
在这张图片中,您可以看到线程增加了 88 MB。其中 arena 和 resource handle count 增加了很多。
在此图片中,您可以看到此 Malloc 中增加了 73 MB。但是这里没有显示方法名称。
所以请提供一些信息来理解这两个屏幕截图。
您可以尝试其他 GC 实现,例如 Java 7 和 probably the default GC in Java 9 中引入的 G1。为此,只需启动您的 Java 应用程序:
-XX:+UseG1GC
Java 8u20 中的 G1 GC 还有一个有趣的功能,可以在堆中查找重复的字符串并 "deduplicate" 它们(这仅在您激活 G1 时有效,而不是默认 Java 8的GC).
-XX:+UseStringDeduplication
在进行此类更改之前,请注意彻底测试您的系统!!!
Here you can find a nice description of the diferent GCs you can use
考虑优化 JVM 选项
在这个my answer you can see information and references how to profile native memory of JVM to find memory leaks. Shortly, see this.
更新
您是否使用了 -XX:NativeMemoryTracking=detail 选项?结果很简单,它们表明 malloc 分配的内存最多。 :) 有点明显。下一步是分析您的应用程序。为了分析本机方法和 Java,我使用(并且我们在生产中使用)带有 perf_events 的火焰图。看看这个 blog post 一个好的开始。
请注意,您的线程内存增加了,很可能您的线程在应用程序中增加了。在 perf 之前,我建议分析线程转储 before/after 以检查 Java 线程数量是否增长以及原因。您可以使用 jstack/jvisualvm/jmc 等
获取线程转储
Java 8 update 152 不存在此问题。早期版本出现此问题的确切根本原因仍未明确确定。
我遇到了完全相同的问题。
堆使用不变,只有元空间增加,NMT 差异显示缓慢但稳定的内存泄漏,特别是在竞技场分配中线程使用的内存。我曾尝试通过设置 MALLOC_ARENAS_MAX=1 env var 来修复它,但这并不奏效。使用 jemalloc/jeprof 分析本机内存分配显示没有可归因于客户端代码的泄漏,而是指向 JDK 问题,因为唯一确凿的证据是 malloc 调用导致的内存泄漏,理论上,应该来自 JVM 代码。
和你一样,我发现升级 JDK 解决了这个问题。我在这里发布答案的原因是因为我知道它解决问题的原因 - 这是一个 JDK 错误,已在 JDK8 u152: https://bugs.openjdk.java.net/browse/JDK-8164293
中修复
错误报告提到 Class/malloc 增加,而不是 Thread/arena,但更进一步的一条评论澄清错误再现清楚地显示 Thread/arena 增加。
我的项目已经开始使用 java 8 来自 java 7。
切换到 java 8 后,我们发现内存消耗随时间增加等问题。
以下是我们所做的调查:
- 只有从 java7 和 java8 迁移后才会出现问题
- 因为元空间是唯一与内存相关的东西,它从 hava 7 更改为 java8。我们监控了元空间,它不会增长超过 20 MB。
- 堆也保持一致。
现在剩下的唯一途径就是分析内存如何分配给 java 7 和 java 8 中的进程,特别是私有字节内存。如有任何想法或链接,我们将不胜感激。
注意:此 javaw 应用程序是基于 swing 的应用程序。
更新 1:使用 NMT 工具分析本机内存并生成与基线相比的内存占用差异。我们发现堆保持不变,但 线程正在泄漏所有这些内存。因此,由于堆没有变化,我假设此泄漏是由于本机代码造成的。
所以挑战仍然开放。关于如何分析所有线程占用的内存的任何想法在这里都会有所帮助。 以下是从本机内存跟踪中获取的快照。
在这张图片中,您可以看到线程增加了 88 MB。其中 arena 和 resource handle count 增加了很多。
在此图片中,您可以看到此 Malloc 中增加了 73 MB。但是这里没有显示方法名称。
所以请提供一些信息来理解这两个屏幕截图。
您可以尝试其他 GC 实现,例如 Java 7 和 probably the default GC in Java 9 中引入的 G1。为此,只需启动您的 Java 应用程序:
-XX:+UseG1GC
Java 8u20 中的 G1 GC 还有一个有趣的功能,可以在堆中查找重复的字符串并 "deduplicate" 它们(这仅在您激活 G1 时有效,而不是默认 Java 8的GC).
-XX:+UseStringDeduplication
在进行此类更改之前,请注意彻底测试您的系统!!!
Here you can find a nice description of the diferent GCs you can use
考虑优化 JVM 选项
在这个my answer you can see information and references how to profile native memory of JVM to find memory leaks. Shortly, see this.
更新
您是否使用了 -XX:NativeMemoryTracking=detail 选项?结果很简单,它们表明 malloc 分配的内存最多。 :) 有点明显。下一步是分析您的应用程序。为了分析本机方法和 Java,我使用(并且我们在生产中使用)带有 perf_events 的火焰图。看看这个 blog post 一个好的开始。
请注意,您的线程内存增加了,很可能您的线程在应用程序中增加了。在 perf 之前,我建议分析线程转储 before/after 以检查 Java 线程数量是否增长以及原因。您可以使用 jstack/jvisualvm/jmc 等
获取线程转储Java 8 update 152 不存在此问题。早期版本出现此问题的确切根本原因仍未明确确定。
我遇到了完全相同的问题。
堆使用不变,只有元空间增加,NMT 差异显示缓慢但稳定的内存泄漏,特别是在竞技场分配中线程使用的内存。我曾尝试通过设置 MALLOC_ARENAS_MAX=1 env var 来修复它,但这并不奏效。使用 jemalloc/jeprof 分析本机内存分配显示没有可归因于客户端代码的泄漏,而是指向 JDK 问题,因为唯一确凿的证据是 malloc 调用导致的内存泄漏,理论上,应该来自 JVM 代码。
和你一样,我发现升级 JDK 解决了这个问题。我在这里发布答案的原因是因为我知道它解决问题的原因 - 这是一个 JDK 错误,已在 JDK8 u152: https://bugs.openjdk.java.net/browse/JDK-8164293
中修复错误报告提到 Class/malloc 增加,而不是 Thread/arena,但更进一步的一条评论澄清错误再现清楚地显示 Thread/arena 增加。