【发布时间】:2019-07-29 18:23:04
【问题描述】:
什么是 Java 中的内部本机内存,我该如何限制它? 我正在使用流行的 java 应用程序之一,例如 tomcat,但是几个小时后我遇到了内存使用率非常高的问题。
我尝试检测问题所在,并检查了 JCMD:
Total: reserved=20207MB, committed=18968MB
- Java Heap (reserved=10000MB, committed=10000MB)
(mmap: reserved=10000MB, committed=10000MB)
- Class (reserved=1069MB, committed=50MB)
(classes #6159)
(malloc=1MB #19368)
(mmap: reserved=1068MB, committed=48MB)
- Thread (reserved=570MB, committed=570MB)
(thread #2039)
(stack: reserved=561MB, committed=561MB)
(malloc=7MB #10216)
(arena=3MB #4076)
- Code (reserved=252MB, committed=52MB)
(malloc=8MB #10918)
(mmap: reserved=244MB, committed=44MB)
- GC (reserved=553MB, committed=553MB)
(malloc=150MB #129854)
(mmap: reserved=403MB, committed=403MB)
- Compiler (reserved=2MB, committed=2MB)
(malloc=2MB #2346)
- Internal (reserved=7726MB, committed=7726MB)
(malloc=7726MB #67913)
- Symbol (reserved=10MB, committed=10MB)
(malloc=8MB #67876)
(arena=2MB #1)
- Native Memory Tracking (reserved=5MB, committed=5MB)
(malloc=1MB #7514)
(tracking overhead=5MB)
- Unknown (reserved=20MB, committed=0MB)
(mmap: reserved=20MB, committed=0MB)
一开始的内存使用是这样的:
Total: reserved=14324MB, committed=12096MB
- Java Heap (reserved=10000MB, committed=9050MB)
(mmap: reserved=10000MB, committed=9050MB)
- Class (reserved=1069MB, committed=49MB)
(classes #6130)
(malloc=1MB #16522)
(mmap: reserved=1068MB, committed=48MB)
- Thread (reserved=400MB, committed=400MB)
(thread #1381)
(stack: reserved=394MB, committed=394MB)
(malloc=4MB #6926)
(arena=2MB #2760)
- Code (reserved=251MB, committed=48MB)
(malloc=8MB #10237)
(mmap: reserved=244MB, committed=41MB)
- GC (reserved=501MB, committed=466MB)
(malloc=98MB #103127)
(mmap: reserved=403MB, committed=368MB)
- Compiler (reserved=1MB, committed=1MB)
(malloc=1MB #1142)
- Internal (reserved=2068MB, committed=2068MB)
(malloc=2068MB #49248)
- Symbol (reserved=9MB, committed=9MB)
(malloc=7MB #67619)
(arena=2MB #1)
- Native Memory Tracking (reserved=5MB, committed=5MB)
(tracking overhead=4MB)
- Unknown (reserved=20MB, committed=0MB)
(mmap: reserved=20MB, committed=0MB)
我认为这可能是应用程序中的内存泄漏,但它可能是堆大小的高使用率。 另外,我在glibc中发现了一些关于bug的文章,所以我在app的systemctl中添加了
Environment="MALLOC_ARENA_MAX=2"
另外,我已经尝试了 4。
我的 GLIBC 版本是:ldd (Debian GLIBC 2.24-11+deb9u3) 2.24
我正在使用具有 24 个线程、24GB RAM 的服务器 Debian 9 x64(更新)。当然是专门针对这个软件的,没有任何其他的应用。 我做了堆转储,(当使用量约为 22gb 时)并在 Eclipse 内存分析器概述中看到:
Size: 2,3 GB Classes: 6,3k Objects: 2,3m Class Loader: 23
您有什么想法,如何检查此内部存储器中的内容,或者如何限制使用? 当内存结束时,我的应用程序一直卡住,但 java 进程仍在运行。只是不工作,但过程仍然存在。
【问题讨论】:
-
您是否在任何网络应用程序中使用任何本机库?还要确保您使用 Java9+ 或 Java 8 和 G1GC 垃圾收集器。
-
我正在使用随软件提供的默认 java。它是 1.8.0_77-b09,但是当我将 java 替换为从网站下载的最新版本时也存在问题。这是启动命令的一部分:“-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:+UseStringDeduplication -XX:ThreadStackSize=256k -Xss256k -XX:MaxMetaspaceSize=2000M -XX:NativeMemoryTracking=detail”
-
另外我忘了写主帖,这个应用程序正在制作〜千线程
-
这篇文章包含了一个很好的文章来检查你是否怀疑涉及本机内存:dzone.com/articles/…。在你的情况下,我会得到一个内存转储并检查是否涉及 DirectByteBuffers - 如果是这样,你可以使用 -Djdk.nio.maxCachedBufferSize 控制那些的大小
标签: java memory memory-leaks out-of-memory