前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM堆外内存问题排查

JVM堆外内存问题排查

作者头像
方丈的寺院
发布2019-08-05 17:30:10
5.4K0
发布2019-08-05 17:30:10
举报
文章被收录于专栏:方丈的寺院方丈的寺院

摘要

JVM 堆内存一般分析的比较多,本篇谈谈堆外内存问题排查,通常我们需要排查堆外内存的原因是系统整个内存使用飙高,但是堆内内存使用正常。这时候就需要分析堆外内存了

堆外内存组成

通常JVM的参数我们会配置

-Xms 堆初始内存 -Xmx 堆最大内存 -XX:+UseG1GC/CMS 垃圾回收器 -XX:+DisableExplicitGC 禁止显示GC -XX:MaxDirectMemorySize 设置最大堆外内存,默认是-xmx-survivor,也就是基本上和-xmx大小相等 -Xss:每个线程的堆栈大小,默认1M -Xmn: 年轻代大小(eden区+2 survivor) -XX:newRatio: 4 年轻代与老年代1:4 -XX:survivorRatio: 8Eden区与survivor大小比值

java整个进程占用的内存:

  • 堆内存
  • metaspace(堆内) JDK8使用metaspace来替代了permsize:永久代大小
  • 堆外内存使用
  • 线程栈空间

堆外内存回收: 堆外内存的回收是通过system.gc()来的,依赖于目前的gc机制。 通常是通过DirectByteBuffer对象来分配堆外内存,gc的时候就是判断这个对象是否被引用,来决定是否回收。

问题排查

首先确认堆占用

  1. jmap 查看heap内存使用情况 jmap -heap pid 可以查看到MetaspaceSize,CompressedClassSpaceSize,MaxMetaSize jmap和jdk版本有关系,有些jdk版本会查看不到内存信息,可以使用jstat来查看统计信息
  2. jstat 收集统计信息
代码语言:javascript
复制
jstat -gc pid 1000

S0C/S0U

S1C/S1U

EC/EU

CCSC/CCSU

YGC/YGCT

FGC/FCGT

GCT

survivor0容量和使用

survivor1容量和使用

Eden

jdk8是meta,以前应是PC,PU

young gc次数和耗时

full gc次数和耗时

total gc时间

代码语言:javascript
复制
排除掉heap的问题

分析堆外情况

NMT(native memory tracking)

使用 在JVM参数中添加 -XX:NativeMemoryTracking=[off | summary | detail]

代码语言:javascript
复制
-XX:NativeMemoryTracking=detail

在JVM运行过程中,使用jcmd获取相关信息 jcmd pid VM.native_memory [summary | detail | baseline | summary.diff | detail.diff | shutdown] [scale= KB | MB | GB]

代码语言:javascript
复制
jcmd pid VM.native_memory detail

baseline个基准,之后会输出diff参数,来和这个基线版本进行比较,可以两次的内存差 NMT报告会显示内存使用情况

类别

含义

Java Heap

堆大小

Thread

线程

Thread Stack

线程栈

更多参考:

https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr022.html

NMT可以得到线程栈大小,排除栈空间影响

pmap 查看进程内存地址空间

代码语言:javascript
复制
pmap -x pid | sort xx

可以结合pmap,和nmt得到内存地址空间。和堆外占用情况了

接下来需要做的就是分析堆外内存的内容了。

gdb dump查看内存空间内容

代码语言:javascript
复制
(gdb) dump binary memory ./file BEGIN_ADDRESS END_ADDRESS

将内存内容dump到文件中,就可以查看到文件中的内容了。 但是这种方式不直观,所以可以使用其他工具

  • gperf google的,使用gperf2.5即可,网上很多安装都说一定要安装libunwind,其实都是瞎抄抄,老版本确实需要,2.5的版本不需要了。 https://blog.csdn.net/unix21/article/details/79161250 另外一个注意点就是虽然heap文件只有1M,但是可以分析出堆外内存的大小。 不过我在实际使用过程中,gperf并没有分析出实际的堆外内存情况,通过pmap可以看出堆外内存占用有几个G,但是gperf始终只有200M
  • Jemalloc https://github.com/jemalloc/jemalloc/releases 安装 ./configurate –enable-prof make sudo make install 配置
代码语言:javascript
复制
export LD_PRELOAD=/usr/local/lib/libjemalloc.so 
export MALLOC_CONF=prof:true,lg_prof_interval:31,lg_prof_sample:17,prof_prefix:/output/jeprof

https://github.com/jemalloc/jemalloc/wiki/Getting-Started

最后分析是dubbo,rpc调用过程中,有很多的数据传输对象,而堆外内存大小又没有限制,导致内存持续飙高

  • -

参考

https://www.cnblogs.com/softidea/p/5267757.html https://blog.csdn.net/u014459326/article/details/53609885 https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html http://lovestblog.cn/blog/2015/05/07/system-gc/ https://blog.csdn.net/kringpin_lin/article/details/26211119 https://blog.csdn.net/jicahoo/article/details/50933469 http://tinylab.org/the-builtin-heap-profiling-of-jemalloc/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 方丈的寺院 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 堆外内存组成
  • 问题排查
    • 首先确认堆占用
      • 分析堆外情况
        • NMT(native memory tracking)
        • pmap 查看进程内存地址空间
        • gdb dump查看内存空间内容
    • 参考
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档