3

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

我正在使用 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)或基于英特尔的标准 Linux 机器(不是 ARM)上运行时,同一个 jar 似乎一切就绪。进程只使用了大约 60 MB 的空间,这是我所期望的。

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

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

更新:

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

-桑迪普

4

1 回答 1

1

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

看看这些答案:

进程内存与堆——JVM

JVM 进程与 JVM 堆内存使用情况

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

于 2012-04-26T08:27:02.623 回答