Java进程内存用量高的分析与解
来源:互联网 发布:上海plc编程培训学校 编辑:程序博客网 时间:2024/04/28 20:15
原文:http://chou.it/2013/09/why-java-consume-a-lot-of-rss-memory/?utm_source=tuicool
首先看一下一个java进程的jmap输出:
然后再用ps看看:
关于这里的几个generation网上资料一大把就不细说了,这里算一下求和可以得知前者总共给Java环境分配了644M的内存,而ps输出的VSZ和RSS分别是7.4G和2.9G,这到底是怎么回事呢?
前面jmap输出的内容里,MaxHeapSize 是在命令行上配的,-Xmx4096m,这个java程序可以用到的最大堆内存。
VSZ是指已分配的线性空间大小,这个大小通常并不等于程序实际用到的内存大小,产生这个的可能性很多,比如内存映射,共享的动态库,或者向系统申请了更多的堆,都会扩展线性空间大小,要查看一个进程有哪些内存映射,可以使用 pmap 命令来查看:
这里可以看到很多anon,这些表示这块内存是由mmap分配的。
RSZ是Resident Set Size,常驻内存大小,即进程实际占用的物理内存大小, 在现在这个例子当中,RSZ和实际堆内存占用差了2.3G,这2.3G的内存组成分别为:
- JVM本身需要的内存,包括其加载的第三方库以及这些库分配的内存
- NIO的DirectBuffer是分配的native memory
- 内存映射文件,包括JVM加载的一些JAR和第三方库,以及程序内部用到的。上面 pmap 输出的内容里,有一些静态文件所占用的大小不在Java的heap里,因此作为一个Web服务器,赶紧把静态文件从这个Web服务器中人移开吧,放到nginx或者CDN里去吧。
- JIT, JVM会将Class编译成native代码,这些内存也不会少,如果使用了Spring的AOP,CGLIB会生成更多的类,JIT的内存开销也会随之变大,而且Class本身JVM的GC会将其放到Perm Generation里去,很难被回收掉,面对这种情况,应该让JVM使用ConcurrentMarkSweep GC,并启用这个GC的相关参数允许将不使用的class从Perm Generation中移除, 参数配置: -XX:+UseConcMarkSweepGC -X:+CMSPermGenSweepingEnabled -X:+CMSClassUnloadingEnabled,如果不需要移除而Perm Generation空间不够,可以加大一点: -X:PermSize=256M -X:MaxPermSize=512M
- JNI,一些JNI接口调用的native库也会分配一些内存,如果遇到JNI库的内存泄露,可以使用valgrind等内存泄露工具来检测
- 线程栈,每个线程都会有自己的栈空间,如果线程一多,这个的开销就很明显了
- jmap/jstack 采样,频繁的采样也会增加内存占用,如果你有服务器健康监控,记得这个频率别太高,否则健康监控变成致病监控了。
关于JVM的几个GC堆和GC的情况,可以用jstat来监控,例如监控进程837每隔1000毫秒刷新一次,输出20次:
几个字段分别含义如下:
S0年轻代中第一个survivor(幸存区)已使用的占当前容量百分比S1年轻代中第二个survivor(幸存区)已使用的占当前容量百分比E年轻代中Eden(伊甸园)已使用的占当前容量百分比Oold代已使用的占当前容量百分比Pperm代已使用的占当前容量百分比YGC从应用程序启动到采样时年轻代中gc次数YGCT从应用程序启动到采样时年轻代中gc所用时间(s)FGC从应用程序启动到采样时old代(全gc)gc次数FGCT从应用程序启动到采样时old代(全gc)gc所用时间(s)GCT从应用程序启动到采样时gc用的总时间(s)结论
因此如果正常情况下jmap输出的内存占用远小于 RSZ,可以不用太担心,除非发生一些严重错误,比如PermGen空间满了导致OutOfMemoryError发生,或者RSZ太高导致引起系统公愤被OOM Killer给干掉,就得注意了,该加内存加内存,没钱买内存加交换空间,或者按上面列的组成部分逐一排除。
这几个内存指标之间的关系是:VSZ >> RSZ >> Java程序实际使用的堆大小
相关的参考资料:
http://www.ibm.com/developerworks/java/library/j-nativememory-linux/
http://www.oracle.com/technetwork/java/javase/index-137495.html
- Java进程内存用量高的分析与解
- JAVA进程内存用量高的分析与解决
- JAVA进程占用高内存原因分析与优化方法
- JAVA进程占用高内存原因分析与优化方法
- JAVA进程占用高内存原因分析与优化方法
- java进程内存分析
- 通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码
- 通过 thread dump 分析找到高CPU耗用与内存溢出的Java代码
- IOS统计内存用量:
- Gloomy对Windows内核的分析(内存与进程管理器)
- Gloomy对Windows内核的分析(内存与进程管理器)
- Gloomy对Windows内核的分析(内存与进程管理器)
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- 【java内存泄漏的定位与分析】
- java内存泄漏的定位与分析
- java类与对象的内存分析
- 对大对象进行排序的算法
- java常用集合类详解
- 程序之美
- Codeforces Round #318 (Div. 2) A、B、C
- web在线播放flv视频
- Java进程内存用量高的分析与解
- Mex 文件
- 正确使用Android性能分析工具——TraceView
- html5--如何用canvas画一个钟
- FCKeditor文件上传配置
- TCP UDP IP 协议分析
- Android 的进程与线程总结
- jQuery制作鼠标悬停水平滑动门切换特效仿阿里妈妈联盟广告切换特效
- nyoj 594 还是A+B 【字符串】