来自:http://longtask.com/review/2014/06/07/java-permgen-outofmemory/

工作以来,第三次出现内存溢出,第一次是ThreadLocal没有remove造成的问题;第二次是ExecutorService没有正确的shutdown造成的问题;这一次的问题在我出手排查之前,已经知道了是permgen在不断的增长,在permgen中主要有Class和Meta信息,常量。

在开始阶段:排除了ThreadLocal可能导致的问题;排除了Thread可能导致的问题;后面就需要从新的突破点找问题了。

     1:基本设置的排查

查找日志中访问量较大的请求的URL:

awk '{print $6}' service-digest.* |awk -F"," '{print $1 ",""1"}'|awk -F"," '{a[$1]+=$2;b[$1]++}END{for(n in a)print a[n] " " n }'|sort -n

查找日志中的调用很多的内容;依然没有发现问题;采用webbench一个个的调用请求来模拟操作,前十名的URL没有发现问题,后面的就没有查看了。

通过线下操作,发现也不是开始怀疑的RMI远程调用的问题;

针对CMS-GC,网上建议开通 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled ,好吧,我们一开始就是开通的。参考:permgen-out-of-memory-reasons

     2:内存使用情况

2.1:查看内存使用情况

jmap -heap pid

2.2:查看permsize的命令

jmap -heap `ps -ef | grep java | grep -v grep` | awk 'NR==44,NR==48'

2.3:触发full gc :

jmap -histo:live pid

2.4:不断的触发full GC 每10分钟观察一下内存的变化情况

PID=`ps -ef | grep java | grep uic | awk '{print $2}'` 
for((i=1;i<10000;i++));do 
jmap -histo:live ${PID} > /tmp/fullgc.log 
jmap -heap ${PID} | awk "NR==42,NR==48" >> heap.log 
echo $i 
sleep 600 
done 

2.5:观察一段时间后(5个小时),分析相关的permsize的内存增长情况

awk '{if(NR%7==0) print $0}' heap.log

     3:查看perm中的情况

jmap -permstat pid

查询的结果类似一下情况:

0x00000000ce58bb18 1 3200 0x00000000cc02c030 dead sun/reflect/DelegatingClassLoader@0x00000000f4067700 
0x00000000cec33d48 1 3088 0x00000000cc02c030 dead sun/reflect/DelegatingClassLoader@0x00000000f4067700 
0x00000000ce39c8b0 1 1944 0x00000000cc02c030 dead sun/reflect/DelegatingClassLoader@0x00000000f4067700 
0x00000000ce8ab270 1 3104 null dead sun/reflect/DelegatingClassLoader@0x00000000f4067700 
0x00000000ceb1d108 1 3104 0x00000000cc02c030 dead sun/reflect/DelegatingClassLoader@0x00000000f4067700

total = 1600 11325 60491768 N/A alive=1, dead=1599 N/A

不是反射的问题。(dead sun/reflect/DelegatingClassLoader)

     4:查看JDK的相关垃圾回收情况

我们使用了CMS GC,过程中发现的GC日志看不出任何问题。

PS:未来我们找个时间专门讨论一下CMS GC的过程,方便我们在未来的垃圾处理过程中找到更加合理的方法去处理问题。

     5:查看perm中的类加载情况

在启动的脚本中打开-verbose:class来查看运行的过程中到底多少个类被加载了。【verbose和verbose:class意义相同, 还有-verbose:gc, -verbose:jni】

JAVA_OPTS="${JAVA_OPTS} -verbose:class"

启动脚本中把输出内容从 /dev/null 2>&1 & 修改为 >${PWD}/jvm.log

我们通过jvm的日志发现如下奇怪的日志:

[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_249 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_250 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_251 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_252 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_253 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_254 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]
[Loaded com.hqb360.uic.dao.point.entity.BonusPointDetail$$BulkBeanByCGLIB$$5a972456_255 from file:/opt/jetty/work/jetty-0.0.0.0-8080-uic.war-_uic-any-/webapp/WEB-INF/lib/cglib-2.2.2.jar]

uic.dao.point.entity.BonusPointDetail的类一直在perm中增加,每次都在复制,没有重用,也没有被垃圾回收。问题基本就定位到这个地方。

     6:找出问题的具体原因

6.1:去掉类中的反射,发现问题没有解决。空欢喜了一场!!!!

6.2:反复的测试调用的页面,发现在插入操作的过程中,会出现步骤5中perm class日志的情况。针对

INSERT INTO bonus_point_detail (<isNotEmpty property="id">id,</isNotEmpty>……gmt_created,gmt_modified)VALUES (<isNotEmpty property="id">#id#,</isNotEmpty>……now(),now())

这样的情况,我们修改为:

INSERT INTO bonus_point_detail (id,……gmt_created,gmt_modified)VALUES (#id#,……now(),now())

后续测试一下,发现问题解决,permgen不再持续增长;当某个内容写操作比较多的时候,直接导致permgen里面有大量的类消息,从而导致了内存溢出。

待处理:我们将下次讨论为什么不能在insert的时候使用isNotEmpty的问题。

java permgen内存泄漏问题处理相关推荐

  1. 使用Java创建内存泄漏

    我刚刚接受采访,并被要求使用Java造成内存泄漏 . 不用说,我对如何开始创建它一无所知. 一个例子是什么? #1楼 最近,我遇到了一种更细微的资源泄漏. 我们通过类加载器的getResourceAs ...

  2. java程序内存泄漏场景及预防

    为什么80%的码农都做不了架构师?>>>    虽然jvm有垃圾回收机制,如果程序编写不注意某些特定规则,仍然会导致java程序内存泄漏,最终可能出现OutOfMemory异常. 1 ...

  3. Java的内存泄漏和垃圾回收机制

    JAVA会产生内存泄露吗?首先,答案是肯定的. Java尽管有垃圾回收器,但依旧存在泄漏. Java内存泄漏跟C/C++内存泄漏的概念不一样:C/C++的内存泄漏是指Malloc了一些资源.最后没有f ...

  4. java static内存泄漏_Java中的内存泄漏

    内存泄漏是指不再使用的对象持续占有内存空间而得不到及时释放,从而造成内存空间的浪费称为内存泄漏.比如,长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄漏,尽管短生命周期对象已经不再需要,但是 ...

  5. 介绍 Java 的内存泄漏

    java最明显的一个优势就是它的内存管理机制.你只需简单创建对象,java的垃圾回收机制负责分配和释放内存.然而情况并不像想像的那么简单,因为在Java应用中经常发生内存泄漏.脚本代码 本教程演示了什 ...

  6. 内存泄漏java例子_一次线上Java应用内存泄漏分析实例

    由于JVM的内存管理采用GC垃圾自动回收机制,这使得Java程序员在编程的时候确实可以从内存管理中释放出来,但这也引发了另外一个大问题,一旦Java应用出现内存泄漏的时候,常常让人措手不及,陷入无从下 ...

  7. java final 内存泄漏_干货详解:一文教你如何避免内部类中的内存泄漏

    我先假设读者已经熟悉在Java代码中使用嵌套类的基础知识.在本文里,我将展示嵌套类的陷阱,内部类在JVM中引起内存泄漏和内存不足错误的地方.之所以会发生这种类型的内存泄漏,是因为内部类必须始终能够访问 ...

  8. java 内存泄漏样例_一次线上Java应用内存泄漏分析实例

    由于JVM的内存管理采用GC垃圾自动回收机制,这使得Java程序员在编程的时候确实可以从内存管理中释放出来,但这也引发了另外一个大问题,一旦Java应用出现内存泄漏的时候,常常让人措手不及,陷入无从下 ...

  9. java缓存内存泄漏_java – getMethod是缓存并导致内存泄漏

    我正在使用自动生成的Java类来执行特殊方法.因此,我必须通过反射调用方法. 此执行由Swing Thread触发,因为该方法(从"unknown"类调用)正在更新UI元素.每次执 ...

最新文章

  1. DATAGRID学习
  2. Exchange Server2013 系列九:常规配置
  3. AIX 中关于文件存储的相关命令
  4. html 首行缩进2个汉字
  5. 从流水中倒推算出销量为多某值的日期
  6. mysql 输出参数 sql语句_MySQL: 详细的sql语句
  7. python 替换文本 通配符_使用通配符搜索和替换文本文件中的字符串
  8. 巧用Calendar求解黑色星期五问题(洛谷P1202题题解,Java语言描述)
  9. 【机器学习实践】Jupyter Notebook安装 侧边导航栏功能 操作及其他常用扩展功能介绍...
  10. Tavas and Karafs 二分+结论
  11. 手机中必备的黑科技App,个个好用至极,现在的你一定需要
  12. 爬虫实例6 爬取联英人才网147页招聘信息,并导入数据库
  13. Understanding LSTM Networks(理解LSTM网络-colah‘s blog)
  14. thinkphp上传图片并jquery预览
  15. 解决windows虚机系统时间与北京时间相差8小时
  16. Android 免root抓包
  17. chariot iperf使用_ixchariot吞吐量测试
  18. 如何设计好的RESTful API之安全性
  19. 编译参数-Wl和rpath的理解
  20. 【每周CV论文推荐】基于GAN的对抗攻击,适合阅读那些文章入门?

热门文章

  1. 部署docker-consul群集,Harbor构建Docker私有仓库
  2. 部署LAMP论坛平台(Linux,Apache,MySQL,PHP)
  3. cors跨域_跨域,不止CORS
  4. python调用窗口_如何调用一个函数并在另一个窗口中打开?
  5. python动态规划图解_动态规划案例之python实现(一)
  6. 关闭linux终端,查看、关闭登录到linux的终端
  7. 学校计算机数据采集处理系统,一种计算机数据采集处理分析系统的制作方法
  8. mongodb启动成功连不上_MySQL数据导入到MongoDb教程
  9. 微信读书vscode插件_跟我一起读源码 – 如何阅读开源代码
  10. 编程隐藏child指定列_简单的Excel VBA编程问题解答——完美Excel第183周小结