最近一个上线运行良好的项目出现用户无法登录或者执行某个操作时,有卡顿现象。查看了日志,出现了大量的java.lang.OutOfMemoryError: GC overhead limit exceeded错误。

oracle官方给出了这个错误产生的原因和解决方法:

Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded
Cause: The detail message "GC overhead limit exceeded" indicates that the garbage collector is running all the time and Java program is making very slow progress. After a garbage collection, if the Java process is spending more than approximately 98% of its time doing garbage collection and if it is recovering less than 2% of the heap and has been doing so far the last 5 (compile time constant) consecutive garbage collections, then a java.lang.OutOfMemoryError is thrown. This exception is typically thrown because the amount of live data barely fits into the Java heap having little free space for new allocations.
Action: Increase the heap size. The java.lang.OutOfMemoryError exception for GC Overhead limit exceeded can be turned off with the command line flag -XX:-UseGCOverheadLimit.

原因:
大概意思就是说,JVM花费了98%的时间进行垃圾回收,而只得到2%可用的内存,频繁的进行内存回收(最起码已经进行了5次连续的垃圾回收),JVM就会曝出ava.lang.OutOfMemoryError: GC overhead limit exceeded错误。

java运行环境包含了一个内置的Garbage Collection (GC)垃圾回收进程,用于对不在使用的内存区域进行回收,释放被占用的内存,jvm会根据程序的运行情况,执行GC垃圾回收操作。java语言,程序员只需关注内存的分配,无需关注内存的回收。

而其他大多数的编程语言,却需要程序员手工编写分配和释放内存的代码。

这种机制也会有一些问题,就是被占用的内存,经过多次长时间的GC操作都无法回收,导致可用内存越来越少,俗称内存泄露,JVM就会报java.lang.OutOfMemoryError: GC overhead limit exceeded错误。

这个是jdk1.6新增的错误类型。

如果没有这个异常,会出现什么情况呢?经过垃圾回收释放的2%可用内存空间会快速的被填满,迫使GC再次执行,出现频繁的执行GC操作, 服务器会因为频繁的执行GC垃圾回收操作而达到100%的时使用率,服务器运行变慢,应用系统会出现卡死现象,平常只需几毫秒就可以执行的操作,现在需要更长时间,甚至是好几分钟才可以完成。

解决方法:
1、增加heap堆内存。
2、增加对内存后错误依旧,获取heap内存快照,使用Eclipse MAT工具,找出内存泄露发生的原因并进行修复。
3、优化代码以使用更少的内存或重用对象,而不是创建新的对象,从而减少垃圾收集器运行的次数。如果代码中创建了许多临时对象(例如在循环中),应该尝试重用它们。
4、升级JDK到1.8,最起码也是1.7,并使用G1GC垃圾回收算法。
5、除了使用命令-xms1g -xmx2g设置堆内存之外,尝试在启动脚本中加入配置:

-XX:+UseG1GC -XX:G1HeapRegionSize=n -XX:MaxGCPauseMillis=m  
-XX:ParallelGCThreads=n -XX:ConcGCThreads=n

还有一个非常不建议使用的解决方法:
在启动脚本中添加-XX:-UseGCOverheadLimit命令。这个方法只会把“java.lang.OutOfMemoryError: GC overhead limit exceeded”变成更常见的java.lang.OutOfMemoryError: Java heap space错误。

我是如何解决这个问题的呢?
首先我的项目是在jdk1.8,64位操作系统上运行,服务器物理内存64G,内存足够,当时分配的4G的内存,并且运行了稳定运行了一年,没有出现过内存溢出的问题。

所以我判断是内存泄漏,内存泄露很隐秘,基本是代码的原因,有大量的对象占用内存,又不能被GC回收,久而久之就出现内存不足,无法给新建的对象分配空间,曝出GC overhead limit exceeded。

经过分析内存,找出原因所在,有段代码使用while循环,不停的new对象,占用了大量的内存,修改代码之后,问题即解决。

GC overhead limit exceeded问题归根结底还是代码的问题,和内存无关,代码中出现了大量占用内存的对象。

posted @ 2019-10-29 00:04 alunbar 阅读(82616) 评论(0) 推荐(2) 编辑
摘要: 上周末,一个同事,转行去卖海鲜,店开张时请我去他店里吃饭,酒过三巡,他说:"真佩服你,写代码13年了,还这么有激情,是什么支撑你写下去的?" 听完,我没有回答,只是笑笑。心里在盘点着这几年有多少个兄弟离开了程序员这一行业,到别的行业谋生了。 工作第3年,和自己一起入职的一个同事,考进体制内;工作第4 阅读全文
posted @ 2019-10-19 20:36 alunbar 阅读(497) 评论(0) 推荐(0) 编辑
摘要: 最近半个月,美国著名的Facebook公司,出了好几件大事。第一件事,2019年9月19日,一名陈姓中国软件工程师在Facebook加州总部跳楼自杀。第二件事,2019年10月4日,一名软件工程师在座位上猝死。第三件事,2019年10月7日,Facebook开除了一名要求公开陈姓中国软件工程师跳楼自 阅读全文
posted @ 2019-10-13 21:34 alunbar 阅读(1559) 评论(10) 推荐(13) 编辑
摘要: Java提供了三个类,用于处理字符串,分别是String、StringBuffer和StringBuilder。其中StringBuilder是jdk1.5才引入的。 这三个类有什么区别呢?他们的使用场景分别是什么呢? 本文的代码是在jdk12上运行的,jdk12和jdk5,jdk8有很大的区别,特 阅读全文
posted @ 2019-10-06 18:19 alunbar 阅读(1471) 评论(4) 推荐(3) 编辑
摘要: 记得刚大学毕业时,为了应付面试,疯狂的在网上刷JAVA的面试题,很多都靠死记硬背。其中有道面试题,给我的印象非常之深刻,有个大厂的面试官,顺着这道题目,一直往下问,问到java虚拟机的知识,最后把我给问住了。 我当时的表情是这样的: 后来我有机会面试别人了,也按照他的思路出面试题,很多已经工作了2年 阅读全文
posted @ 2019-09-30 19:58 alunbar 阅读(523) 评论(0) 推荐(0) 编辑
摘要: 2005年,sun公司推出了jdk1.5,同时推出的注解功能吸引了很多人的目光,使用注解编写代码,能够减轻java程序员繁琐配置的痛苦。 使用注解可以编写出更加易于维护,bug更少的代码。 注解是什么呢?按照官方的说法,注解就是元标签,可以添加到你的代码,并应用于包声明、类型声明、构造函数、方法、字 阅读全文
posted @ 2019-09-08 10:48 alunbar 阅读(1669) 评论(2) 推荐(1) 编辑
摘要: 最近公司招了几名刚毕业的大学生,在给他们培训的过程中,讲到反射,他们有些人听不懂,对反射的概念云里雾里的,不知道反射有什么用。 因此就有了本文的诞生。 反射是java提供的一个重要功能,可以在运行时检查类、接口、方法和变量等信息,无需知道类的名字,方法名等。还可以在运行时实例化新对象,调用方法以及设 阅读全文
posted @ 2019-08-30 20:57 alunbar 阅读(706) 评论(1) 推荐(1) 编辑
摘要: 最近一个运行了4年的javaee web项目,经常接到客户反馈系统无法打开。登录服务器查看服务,发现是tomcat自动关闭了。基本是3到4天发生一次。 运维人员开始以为是其他服务杀死了tomcat服务,没放在心上,解决方法就是直接重启tomcat。 最终捅了篓子,运维人员被客户投诉,扣了一个月的绩效 阅读全文
posted @ 2019-08-14 22:02 alunbar 阅读(3359) 评论(2) 推荐(8) 编辑
摘要: 用centos时,root用户一般都是超级管理员使用的,一般不轻易给别人,但是有时候同事安装软件时需要root账号,又不得不给,只能重新建一个用户,并赋予管理员权限。下面介绍创建用户并赋予管理员权限的方法步骤: 1、新建用户,这里新建一个temp_test的用户 adduser temp_test 阅读全文
posted @ 2019-05-18 09:11 alunbar 阅读(21028) 评论(0) 推荐(2) 编辑
摘要: 2007年,Dwight Merriman, Eliot Horowitz和Kevin Ryan成立10gen软件公司,在成立之初,这家的公司目标进军云计算行业,为企业提供云计算服务。在开发云计算产品时,他们准备开发一个类似于数据库的组件,为云计算产品提供存储服务。当时是关系型数据库一统天下的时间, 阅读全文
posted @ 2019-03-27 08:58 alunbar 阅读(3531) 评论(1) 推荐(3) 编辑
点击右上角即可分享
微信分享提示