javaw 进程的私有字节数增加 java 8

private bytes increase for a javaw process in java 8

我的项目已经开始使用 java 8 来自 java 7。

切换到 java 8 后,我们发现内存消耗随时间增加等问题。

以下是我们所做的调查:

现在剩下的唯一途径就是分析内存如何分配给 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 选项

  1. Parallel Collector(吞吐量收集器)

    -XX:+UseParallelGC

  2. 并发收集器(低延迟收集器)

    -XX:+UseConcMarkSweepGC

  3. 使用字符串重复删除器

    -XX:+UseStringDeduplication

  4. 优化紧凑率

    -XXcompactRatio: 并参考 link1 link2

在这个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 增加。