谈论JVM内存溢出问题
2016-06-30 17:46
369 查看
1、问题描述
这两天公司项目的项目进行测试,服务器会偶尔出现访问不通,EJB远程调用全部失效的情况,经过对JVM监控,发现是JVM内存FullGC造成系统停顿造成的。目前基础系统jboss启动jvm内存设置为3G,之前出现过out of memory heap 的错误。现在正常开发情况下,基础系统平均一两天就会因为内存爆满,出现系统停顿,不得不重启jboss来解决。
一开始一直认为EJB不稳定,一般个别接口远程调用不通,经过查看系统日志发现有OOM的异常。
相关工具:
Jconsole:jdk自带的jvm简单监控工具,直接cmd—jconsole即可使用
Jvisualvm:jconsole高级版本,比jconsole信息详细些,cmd-jvisualvm即可使用
Jprofiler:性能监控工具,可以同步检测程序运行过程中jvm的各个参数,类,线程的实时情况。同时也可以分析dump。
EclipeseMemory Analyzer:多用于离线分析dump日志,可以给出内存溢出的建议,工具具体使用较为专业,需要对jvm内部结构了解。
监测情况如图:
主要是老年代内存不足,及FullGC造成的。
名词介绍:
新生代:主要用来存放新生的对象,对象更新速度快,短时间内产生大量的“死亡对象”
老年代:主要存放应用中生命周期长得内存对象(具体介绍看百度)
引起内存溢出的原因可能是:
1、JVM参数使用默认的不能够满足我们的需要,需要根据我们系统的需要对新生代和老年代进行内存分配。
2、大量使用本地缓存(如大量使用hashmap作为K/V缓存)的应用,在逻辑集群造成即到达的内存浪费,因为每个逻辑节点上都有一份缓存。
这时候可以考虑把本地缓存改为集中式缓存。·
3、不恰当的数据结构导致内存占用过大(例如:HashMap<String,String>结构中来存储数据文件空间效率太低)
总结:
通过修改JVM的参数,系统改善不是很明显,只能延缓,不能从根本上解决问题。最根本的着手点还是我们的代码,可以考虑和代码走查的相关负责人配合。优化我们的代码,比如:优化map是很有必要的,代码中是否存在不合理的for循环或者是递归调用,由于循产生过多重复的对象实体,或者是list、map等集合对象是否有使用完后,未清除的问题,导致不能被GC回收。
最终的原因还是由于自己代码中使用多租户+级联导致不能回收,问题的原因知道,但是不清楚为什么他俩放一起使用就不行了,该问题还在研究中。
这两天公司项目的项目进行测试,服务器会偶尔出现访问不通,EJB远程调用全部失效的情况,经过对JVM监控,发现是JVM内存FullGC造成系统停顿造成的。目前基础系统jboss启动jvm内存设置为3G,之前出现过out of memory heap 的错误。现在正常开发情况下,基础系统平均一两天就会因为内存爆满,出现系统停顿,不得不重启jboss来解决。
一开始一直认为EJB不稳定,一般个别接口远程调用不通,经过查看系统日志发现有OOM的异常。
相关工具:
Jconsole:jdk自带的jvm简单监控工具,直接cmd—jconsole即可使用
Jvisualvm:jconsole高级版本,比jconsole信息详细些,cmd-jvisualvm即可使用
Jprofiler:性能监控工具,可以同步检测程序运行过程中jvm的各个参数,类,线程的实时情况。同时也可以分析dump。
EclipeseMemory Analyzer:多用于离线分析dump日志,可以给出内存溢出的建议,工具具体使用较为专业,需要对jvm内部结构了解。
监测情况如图:
主要是老年代内存不足,及FullGC造成的。
名词介绍:
新生代:主要用来存放新生的对象,对象更新速度快,短时间内产生大量的“死亡对象”
老年代:主要存放应用中生命周期长得内存对象(具体介绍看百度)
引起内存溢出的原因可能是:
1、JVM参数使用默认的不能够满足我们的需要,需要根据我们系统的需要对新生代和老年代进行内存分配。
2、大量使用本地缓存(如大量使用hashmap作为K/V缓存)的应用,在逻辑集群造成即到达的内存浪费,因为每个逻辑节点上都有一份缓存。
这时候可以考虑把本地缓存改为集中式缓存。·
3、不恰当的数据结构导致内存占用过大(例如:HashMap<String,String>结构中来存储数据文件空间效率太低)
总结:
通过修改JVM的参数,系统改善不是很明显,只能延缓,不能从根本上解决问题。最根本的着手点还是我们的代码,可以考虑和代码走查的相关负责人配合。优化我们的代码,比如:优化map是很有必要的,代码中是否存在不合理的for循环或者是递归调用,由于循产生过多重复的对象实体,或者是list、map等集合对象是否有使用完后,未清除的问题,导致不能被GC回收。
最终的原因还是由于自己代码中使用多租户+级联导致不能回收,问题的原因知道,但是不清楚为什么他俩放一起使用就不行了,该问题还在研究中。
相关文章推荐
- Java 6 JVM参数选项大全(中文版)
- Gson.toJson()时内存溢出StackOverflowError
- ASP在ACCESS中模糊查询"内存溢出"的解决方法
- 深入解析JVM对dll文件和对类的装载过程
- Android 异步获取网络图片并处理导致内存溢出问题解决方法
- 基于Java内存溢出的解决方法详解
- JVM Tomcat性能实战(推荐)
- Java虚拟机JVM性能优化(二):编译器
- Java程序员必须知道的5个JVM命令行标志
- tomcat6.0 /7.0安装版内存溢出设置方法
- 关于PHP内存溢出问题的解决方法
- Android编程之内存溢出解决方案(OOM)实例总结
- Android加载图片内存溢出问题解决方法
- 浅谈C#互操作的内存溢出问题
- mongodb错误tcmalloc: large alloc out of memory, printing stack and exiting解决办法
- phpExcel导出大量数据出现内存溢出错误的解决方法
- Java虚拟机JVM性能优化(三):垃圾收集详解
- 简单谈谈JVM、JRE和JDK的区别与联系
- 解析Java虚拟机中类的初始化及加载器的父委托机制
- 一个JSP页面导致的tomcat内存溢出的解决方法