java 进程内存占用排查. 除了堆之外

java 内存可分为: 堆和meta space .

查看堆:

    jmap -heap pid

查看metaSpace:

   使用 jstat -gc pid mc mu.

内存历史,如果没有web系统的话.:

 sar -r -s 13:00:00 -e 14:00:00

 https://linux.die.net/man/1/sar

查看进程内的其他占用: 

   top 里的rs占用 减去 jmap -heap 里的占用.  VIRT=swap+RES . virtual ; Resident 常驻

    /proc/$PID/maps smaps是更详细的信息

    pamp pid : anon 的意思是内存分配.

    $cat /proc/1756/maps | grep deleted 来搜索"游离态的mmapFile,一旦游离态里,这里会显示出文件已被 deleted "

    

下面我们简单说明一下samps里面的内容,

  • 00400000-00409000 是该虚拟内存段的开始和结束位置

  • r-xp 内存段的权限,rw是指可读写,x是指可执行,p是指私有,如果是s则为共享

  • 00000000 该虚拟内存段在对应的映射文件中的偏移量

  • 08:02 文件的主设备和次设备号

  • 1361644 被映射到虚拟内存的文件的索引节点号

  • /sbin/init 被映射到虚拟内存的文件名称

  • Size 是进程使用内存空间,并不一定实际分配了内存(VSS)

  • Rss 是实际分配的内存

  • Shared_Clean 和其他进程共享的未改写页面

  • Shared_Dirty 和其他进程共享的已改写页面

  • Private_Clean 未改写的私有页面页面

  • Private_Dirty 已改写的私有页面页面

  • Swap 存在于交换分区的数据大小(如果物理内存有限,可能存在一部分在主存一部分在交换分区)

  • Pss是平摊计算后的使用内存(有些内存会和其他进程共享,例如mmap进来的)

通过 cat /proc/$(pid)/smaps 能查看所有进程的使用情况,若你想要查看某个进程所使用的swap只需要,

1
awk  '/^Swap:/ {SWAP+=$2}END{print SWAP" KB"}'  /proc/ $(pid) /smaps

如何解决分析堆外存异常:

    表现: 进程每隔几个小时就异常退出

    日志描述: 崩溃hs_err.log内容得知,原来是jni ping引入的dll调用异常导致java.exe进程异常中止了.

java -XX:ErrorFile=/var/log/java/java_error%p.logJVM致命错误日志(hs_err_pid.log)分析

     原因逻辑关联:

           当内存达到JVM中设置的MaxDirectMemorySize值时,dll就会出现内存访问异常错误,最终导致java.exe进程异常退出了

     1. https://elasticsearch.cn/article/178

     2. 可以通过-XX:MaxDirectMemorySize来指定最大的堆外内存大小,当使用达到了阈值的时候将调用System.gc来做一次full gc,以此来回收掉游离状态的堆外内存。[堆外存垃圾回收]

      GZIP造成JAVA Native Memory泄漏案例


  另外一篇方法论文章: JAVA使用堆外内存导致swap飙高 #29https://github.com/nereuschen/blog/issues/29




java -XX:MaxMetaspaceSize=50m MetadataOOMSimulator 100000000https://stackoverflow.com/questions/39084331/why-metaspace-size-is-twice-as-big-as-used-metaspace?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

UseCompressedClassPointers

CompressedClassSpaceSize : 涉及到metaspace的分区: kclass,nonKclass.

这也是为什么,明明配置了

MetaspaceSize            = 268435456 (256.0MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)

   MaxMetaspaceSize         = 268435456 (256.0MB)

但是jstat显示

S0C       S1C          S0U    S1U      EC          EU          OC         OU           MC           MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT

174720.0 174720.0  0.0   31685.6 1747712.0 373119.2 2097152.0   517354.5  142208.0 139045.9 16512.0 15730.3   6325  194.007   0      0.000  194.007


附件:https://blog.csdn.net/fei33423/article/details/80136920

gperftools做堆外内存分析(案例JVM Inflater 内存泄漏分析)

提到了崩溃日志,JNI引起的堆外内存泄漏问题分析 https://blog.csdn.net/cza55007/article/details/50755011#commentBox


附录:

  • Address: 内存开始地址
  • Kbytes: 占用内存的字节数(KB)
  • RSS: 保留内存的字节数(KB)
  • Dirty: 脏页的字节数(包括共享和私有的)(KB)
  • Mode: 内存的权限:read、write、execute、shared、private (写时复制)
  • Mapping: 占用内存的文件、或[anon](分配的内存)、或[stack](堆栈)
  • Offset: 文件偏移
  • Device: 设备名 (major:minor)



JVM致命错误日志(hs_err_pid.log)分析


自己的另外一篇文章: 

进程消失排查系统 oom排查 https://blog.csdn.net/fei33423/article/details/80747700

你可能感兴趣的:(shell,jvm)