我正在尝试测量linux上进程(java程序)的内存使用情况,并有两个与此相关的问题:
我尝试使用脚本ps_mem.py(来自/ proc / $ PID / smaps的值)和总内存使用量的峰值约为135MB(私有和共享内存)。共享内存量小于1MB。尝试使用Valgrind与massif工具valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram
在内存使用高峰时产生大约10MB
根据我的理解,堆是存储程序变量的地方,这是否意味着两个方法之间的差异是代码本身占用的空间(包括jvm)?
如果相同的程序有不同的RAM或/和使用不同的处理器(ARM或x86),它们是否在不同的机器上使用不同的内存量?
答案 0 :(得分:3)
smaps
中的许多共享内存映射都由磁盘上的库/二进制文件直接支持。虽然它们的占地面积很重要,但它不那么重要,因为系统可以随时丢弃这些页面,并在需要时再次从磁盘重新加载它们。答案 1 :(得分:3)
除此之外还有一个类似的问题,在这里回答同样的问题,让人们知道linux proc stat vm info目前是不准确的。
Valgrind可以显示详细信息,但它会显着降低目标应用程序的速度,并且大多数时候它会改变应用程序的行为。
我假设每个人都想知道WRT“内存使用情况”如下...
在linux中,单个进程可能使用的物理内存量大致可分为以下几类。
我更希望获得如下数字,以获得最少开销的实数
你必须总结这些,以便将ps显示为RSS并将更准确的数字分开而不要混淆
/ proc /(pid)/ status试图显示这些数字,但它们都失败了
因此,我没有尝试将[anon],[stack]标记为正确地映射到每个映射,而是希望如此
Linux内核人员将主要处理proc入口代码以汇总并显示这些M.a.p.d,M.a.p.c,M.n.p.d,....数字。
嵌入式linux的人会很高兴恕我直言。
M.a.p.d:
awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Dirty/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps
M.a.p.c:
awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Clean/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps
M.n.p.d:......等等
答案 2 :(得分:1)
对于#1,共享内存是由多个进程使用的内存(可能)。这基本上是如果您在多个进程中运行相同的二进制文件或不同的进程正在使用共享库。堆是存储已分配内存的位置(在Java中使用new
时)。由于Java有自己的VM,因此它会在您在java代码中看不到的进程级别分配大量内存。我认为是的,135 MB的大部分来自JVM代码/数据本身。但是,堆栈也占用了内存(当你进行函数调用并有局部变量时)。
对于#2,当我们让内存等于RAM +交换空间时,不同数量的RAM不会影响使用多少“内存”。但是,不同的处理器(特别是如果我们谈论的是32位与64位)可能会使用不同的内存量。此外,编译进程的方式可能会改变使用的内存量,因为您可以指示编译器优化内存占用超速,以及完全禁用部分或全部优化。
答案 3 :(得分:0)
您可能想看看JConsole。根据您的测量目的,事情可能会很棘手。如果您想知道Java程序的内存使用情况,那么测量进程内存使用情况的工具将是不准确的,因为它们将显示JVM和程序使用的内存。
至于massif工具,您应该知道JVM的某些部分将存储在堆栈中,并且Java代码本身可能在堆上(因为它是JVM的变量),我不太了解JVM说。