我已经被这个问题困扰很久了,没有任何提示。如果有人可以提供帮助,我将不胜感激。
我正在使用 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 访问有关,虽然还不确定它是什么。随着我取得一些进展,将不断更新。
-桑迪普