2009-12-11 65 views
4
进程的内存使用情况

我试图以测量过程的Linux上的内存使用量(Java程序),有两个相关的疑问:测量在Linux上

  1. 我尝试使用脚本ps_mem.py (从/ proc/$ PID/smaps中总结值),总内存使用率的峰值约为135MB(私有和共享内存)。共享内存量小于1MB。试图使用Valgrind与地块工具valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram在内存使用高峰时产生大约10MB。
    现在,据我了解,堆是我的程序的变量存储的地方,这是否意味着两种方法之间的区别是代码本身(包括jvm)所占用的空间?

  2. 如果不同的机器有不同数量的RAM或/和使用不同的处理器(ARM或x86),相同的程序是否在不同的机器上使用不同数量的内存?

回答

3
  1. 取决于。
    • smaps中的许多共享内存映射直接由磁盘上的库/二进制文件支持。尽管它们的占用空间很重要,但它并不重要,因为系统可以随时丢弃这些页面,并在需要时再次从磁盘重新加载它们。
    • 任何肮脏或私密的东西都只属于当前进程(当然,如果您的程序没有执行程序,则进程树会分叉)。这更重要,因为如果需要将这些页面从内存中移出,系统必须将它们保存为交换。
    • 什么山地测量可能与后者相关。但是,JVM本身(没有您的程序)所占用的内存都在两者中。
  2. 是的。 Java或其使用的库可能会根据可用RAM的大小调整其内存模型。在不同的体系结构上,您使用的是完全不同的二进制文件,它们可能更大或更小,或者使用不同的排列方式或使用不同的JIT和内存管理策略。
1

对于#1,共享内存是内存(可能)被多个进程使用。这基本上是如果您在多个进程中运行相同的二进制文件或不同的进程正在使用共享库。堆是分配内存的地方(当你在Java中使用new时)。由于Java有它的虚拟机,因此它在进程级别分配了大量内存,而这些内存在Java代码中没有看到。我认为是的,大部分135 MB来自JVM代码/数据本身。但是,也有堆栈占用的内存(当你进行函数调用并且有局部变量时)。

对于#2,当我们让内存等于RAM +交换空间时,不同数量的RAM不会影响使用多少“内存”。但是,不同的处理器(特别是如果我们谈论32位与64位)可能会使用不同数量的内存。另外,编译过程的方式可能会改变使用的内存量,因为您可以指示编译器针对速度对内存占用进行优化,以及完全禁用部分或全部优化。

0

您可能想看看JConsole。根据测量的目的,事情可能会非常棘手。如果您想知道Java程序的内存使用情况,那么衡量进程内存使用情况的工具将不准确,因为它们会显示JVM以及您的程序使用的内存。

至于massif工具,你应该知道JVM的一部分将被存储在堆栈上,并且java代码本身可能在堆上(因为它是JVM的一个变量),我不知道足够多关于JVM的说法。

3

除此之外,还有一个类似的问题,并在这里回答相同的问题,让人们知道当前的linux proc stat vm信息不准确。
Valgrind可以显示详细信息,但会显着降低目标应用程序的速度,并且大部分时间会改变应用程序的行为。

我假定每个人都想知道WRT“内存使用量”如下...
在linux中,单个进程可能使用的物理内存量大致可以分为以下几类。

  • 马匿名映射内存
    • .P私人
      • .D脏==的malloc/mmapped堆和栈分配和写入内存
      • .C干净==的malloc/mmapped堆和堆栈内存一次分配,写入,然后释放,但不回收
    • .s共享
      • .D脏==应该没有
      • .C干净==应该没有
  • 锰命名映射内存
    • .P私人
      • .d脏==文件mmapped写入内存专用
      • .C干净==映射程序/库文本私有映射
    • .S共享
      • .D脏==文件mmapped写入内存共享
      • .C干净==映射库文本共享映射

我宁愿得到数目如下中至少奥雅纳得到实数rhead。
你必须对这些进行总结,以便将ps节目分为RSS,并获得更准确的数字,以免混淆。
/proc /(pid)/ status会尝试显示这些数字,但它们失败。
因此,我不希望为每个映射标记[anon],[stack],我的愿望是 ,即Linux内核人员将mainline proc入口代码汇总并显示这些Mapd,Mapc,Mnpd ....数字。
嵌入式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:...等