Java 本机内存使用情况

Posted

技术标签:

【中文标题】Java 本机内存使用情况【英文标题】:Java native memory usage 【发布时间】:2011-02-14 22:54:38 【问题描述】:

是否有任何工具可以知道我的 java 应用程序使用了多少本机内存? 我的应用程序内存不足: 当前设置是: -Xmx900m

计算机,Windows 2003 Server 32 位,RAM 4GB。

在 Windows 上也将 boot.ini 更改为 /3GB,会有什么不同吗? 如果设置为 Xmx900m,可以为这个进程分配多少本机内存?是1100m吗?

【问题讨论】:

您遇到了哪个 OutOfMemory 异常?堆空间,Permgen,还是不能创建原生线程?解决方案完全不同。 "无法创建原生线程" 【参考方案1】:

如果您使用例如 jvisualvm(它与 jdk 一起提供),您可以看到您的应用程序正在使用多少内存,您还可以更详细地分析它。

【讨论】:

嗨 Luno,jvisualvm 只为我提供空闲和使用的堆内存,我需要的是空闲的本机内存。我的本机内存快用完了。 是的,@Mirek Pluta 根据 jvisualvm,我有大量的可用堆内存使用量,但我也遇到了“本机内存不足”错误。【参考方案2】:

可用进程空间略小于 2GB - Xmx。 (假设 Sun JVM)您必须将 permgen 空间添加到 Xmx,然后为操作系统的内核内容减去大约 150-200MB 左右。如果真正的问题是真正的内存不足,那么 3GB 开关或减少 Xmx 和 PermGen 空间应该可以缓解它。有时,至少在 Windows 上,操作系统所花的时间比 JVM 愿意等待分配线程的时间要长,而且问题更多的是你在产生垃圾邮件而不是内存不足。您应该有几千个线程的内存空间。在它放弃之前你有多少?

还有一个 -Xss 开关来控制 JVM 要求的线程堆栈大小。 YMMV 如果更改它实际上在 Windows 上是否有任何作用。

【讨论】:

所以你说要知道最大本机内存空间是:2GB - Xmx - Xmx permgen 空间 = 最大本机内存空间。更改为 3GB 是否也会扩展本机内存空间?所以它变成:3GB - Xmx - Xmx permgen space = Max native memory space。是否有任何工具可以实时监控,afaik 我在 jconsole/jvisualvm 中找不到这个数字。非常感谢。 进程浏览器会给你一些相当详细的信息:technet.microsoft.com/en-us/sysinternals/bb896653.aspx Windows 内存管理的深层内部结构很复杂。我不知道是否存在一个简单的公式来获取在任何给定时间您真正拥有多少可用空间的“确切”数字。基本上,您将应用服务器置于生产负载下并调低堆,直到找到既没有没有本机线程也没有堆空间不足的地方。【参考方案3】:

对于后面的人,VMMap 会给你答案。它将显示本机内存分配。以我的经验,我相信在操作系统分配块中的最小数量为 124K 时会忽略 -Xss。操作系统分配会不断翻倍,直到达到 1GB(然后你就完成了。)如果你不能减少你的线程,那么尝试减少你的最大堆和最大 permgen 设置或尝试 /3GB 开关。

【讨论】:

【参考方案4】:

This article 提供了一些关于寻找本机内存问题的有用信息,并解释了您是如何耗尽本机内存的。

【讨论】:

【参考方案5】:

(在我的情况下,我使用 java 8)

添加到命令行:-XX:NativeMemoryTracking=summary

然后启动jcmd <PID> VM.native_memory

你应该得到这样的东西:

Total: reserved=3863657KB, committed=1679977KB
-                 Java Heap (reserved=1843200KB, committed=824320KB)
                            (mmap: reserved=1843200KB, committed=824320KB) 

-                     Class (reserved=1311974KB, committed=298726KB)
                            (classes #52579)
                            (malloc=5350KB #76340) 
                            (mmap: reserved=1306624KB, committed=293376KB) 

-                    Thread (reserved=263278KB, committed=263278KB)
                            (thread #256)
                            (stack: reserved=262140KB, committed=262140KB)
                            (malloc=839KB #1280) 
                            (arena=299KB #510)

-                      Code (reserved=278521KB, committed=164773KB)
                            (malloc=28921KB #37983) 
                            (mmap: reserved=249600KB, committed=135852KB) 

-                        GC (reserved=114897KB, committed=77093KB)
                            (malloc=13729KB #67925) 
                            (mmap: reserved=101168KB, committed=63364KB) 

-                  Compiler (reserved=461KB, committed=461KB)
                            (malloc=330KB #1138) 
                            (arena=131KB #3)

-                  Internal (reserved=13877KB, committed=13877KB)
                            (malloc=13845KB #72978) 
                            (mmap: reserved=32KB, committed=32KB) 

-                    Symbol (reserved=28871KB, committed=28871KB)
                            (malloc=24740KB #275452) 
                            (arena=4131KB #1)

-    Native Memory Tracking (reserved=8393KB, committed=8393KB)
                            (malloc=45KB #523) 
                            (tracking overhead=8348KB)

-               Arena Chunk (reserved=184KB, committed=184KB)
                            (malloc=184KB) 

欲了解更多信息,请参阅https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr007.html

【讨论】:

【参考方案6】:

Native Memory 是 JVM 通常用于其内部操作和执行 JNI 代码的区域。 JVM 使用本机内存进行代码优化以及加载类和库以及中间代码生成。 本机内存的大小取决于操作系统的体系结构和已提交给 Java 堆的内存量。本机内存是加载 JNI 代码或加载 JVM 库或加载本机性能包和代理模块的进程区。 没有可用于调整本机区域大小的 JVM 选项。但我们可以使用以下公式进行近似计算:

NativeMemory = (ProcessSize - MaxHeapSize - MaxPermSize)

在devopsconsole找到这个

【讨论】:

以上是关于Java 本机内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章

调试 - 如何分析反应本机内存使用情况

Golang利用第三方包获取本机cpu使用率以及内存使用情况

Java 本机内存跟踪堆提交的数量远远超过堆转储的总数

使用 JNI 在 Java 调用之间将本机对象保存在内存中

在 Java 中为 JOGL 释放直接缓冲区本机内存

JVM中的本机内存跟踪