【问题标题】:Java process memory usage much more than what Runtime.totalMemory et al methods are tellingJava 进程内存使用量比 Runtime.totalMemory 等方法所告诉的要多得多
【发布时间】:2012-05-06 22:58:12
【问题描述】:

我已经被这个问题困扰很久了,没有任何提示。如果有人可以提供帮助,我将不胜感激。

我正在使用 ARM v7 处理器的设备上运行 Java 应用程序。它安装了 Ubuntu。使用“top”或“free -m”命令查看进程的内存使用量约为 180 MB,这比 Runtime.freeMemory 等方法告诉我的要多得多。

这就是我开始申请的方式:

java -Xcheck:jni -XX:MaxPermSize=25m -Xmx65m -XX:ReservedCodeCacheSize=10m -jar MyAPP.jar myconfig.xml

据我了解,此进程的总内存使用量不应超过25 + 65 + 10 = 100 MB。它可能更多(我不知道的其他非堆空间)。但即便如此,我认为差异也不应该有这么大(80 MB)。

这似乎是“运行时”命令在我的日志中告诉我的内容(我使用这些命令将使用信息打印为调试日志的一部分)。

使用信息:可用处理器:2 JVM 可用的空闲内存:8474344,当前内存使用量:5943576,JVM 允许使用的最大内存:66977792

“顶部”的输出:

PID   USER     PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
3926  linaro   20  0   266m  188m 3636 S  1.0 21.1   0:37.81 java

“free -m”的输出:

Java 进程运行时:

        total       used       free     shared    buffers     cached
Mem:     893         842         51          0         40        216
-/+ buffers/cache:   585        308
Swap:     0          0          0

进程停止时:

         total      used       free     shared    buffers     cached
Mem:      893        656        237          0         40        216
-/+ buffers/cache:   400        493
Swap:      0          0          0

正如我们所见,493 - 308 = 185 与“top”所说的有关此进程的内存使用情况相匹配(之前我认为这台机器上安装了 top 可能存在错误)。

我也对这个进程进行了远程监控,它显示大约 14M 的“已提交”堆空间和大约 20M 的非堆空间。至少堆空间与我从“运行时”命令中得到的相匹配。所以连远程监控工具都好像说内存使用量远小于180M。

最奇怪的部分是,当我在笔记本电脑 (MacBook Pro) 或基于 Intel 的标准 Linux 机器(不是 ARM)上运行时,同一个 jar 似乎一切就绪。进程只使用了大约 60 MB 的空间,这是我所期望的。

还有一点值得一提的是,我在 ARM 设备上使用的 Java VM 是 Oracle 的 Java SE Embedded 版本。

任何知道内存使用差异的人。抱歉问了这么长的问题:-)。

更新:

在对可能消耗内存的 Java 进程的各个部分进行了一些研究之后,我将注意力集中在本机代码交互 (JNI) 上。那是唯一一个我们无法从命令实时参数中限制内存消耗的人。在我的程序中,我使用 sqlite-jdbc 驱动程序来访问数据库。我评论了数据库访问部分,内存使用量下降到 24MB!!! 所以我猜测这个内存差异与这个 sqlite jdbc 访问有关,虽然还不确定它是什么。随着我取得一些进展,我会不断更新。

-桑迪普

【问题讨论】:

    标签: java memory-management embedded


    【解决方案1】:

    您观察到的是 JVM 与进程内存之间的区别。

    看看这些答案:

    Process Memory Vs Heap -- JVM

    JVM Process vs JVM Heap memory usage

    由于您在每个系统上使用不同的 JVM 实现,您可能会有不同的内存行为。

    【讨论】:

    • 我知道堆空间完全在限制范围内。它是我无法弄清楚它被花费在哪里的进程内存。我正在寻找一种方法来确定谁在使用进程内存的哪一部分。我也查看了我的进程的 /proc/id/smaps 输出。似乎有大约 140MB 的内存是匿名映射的,即没有实际的文件可以映射该内存。有没有办法找出谁负责匿名内存分配?
    猜你喜欢
    • 2021-01-25
    • 2021-09-20
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2021-04-03
    • 2016-08-17
    • 1970-01-01
    • 2017-05-24
    相关资源
    最近更新 更多