首页 javaWEB OutOfMemoryError异常的常见原因

OutOfMemoryError异常的常见原因

为啥会出现OutOfMemoryError 内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 集合类中有对对象的…

为啥会出现OutOfMemoryError

内存中加载的数据量过于庞大,如一次从数据库取出过多数据; 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;

代码中存在死循环或循环产生过多重复的对象实体; 使用的第三方软件中的BUG; 启动参数内存值设定的过小;

OutOfMemoryError几种情况

最常见的有这3种

java.lang.OutOfMemoryError: Java heap space

java.lang.OutOfMemoryError: PermGen space

java.lang.OutOfMemoryError: GC overhead limit exceeded

(堆内存溢出)java.lang.OutOfMemoryError: Java heap space

Java heap space,Java应用程序创建的对象存放在这片区域,垃圾回收(Garbage Collection)也发生在这块区域。通常一些比较“重型”的操作可能会导致该异常,比如:需要创建大量的对象,层次比较深的递归操作等。

解决方案有两种,一是优化应用,找到消耗大量内存的地方,然后优化代码或者算法。这种方式比较推荐,但是难度比较大,尤其是在产品环境中出现这种问题,开发人员不能很好的重现问题。第二种方案是提升Java heap size,这种方式虽然感觉有点治标不治本,但是可行性非常高,操作简单。

如果是在tomcat中,出现的这种问题,解决办法是在{tomcat_dir}/bin/catalina.bat中找到如下几行:

在后面加上一行(数字根据自己的需要调整):

 set CATALINA_OPTS=-Xms512m -Xmx512m

(方法区内存溢出)java.lang.OutOfMemoryError: PermGen space

Perm Gen Size(Permanent Generation Size),用来存储被加载的类的定义(class definition)和元数据(metadata),比如:Class Object和Method Object等。这是内存中的一块永久保存区域,JVM的垃圾回收不会触及这块区域。通常在加载一个非常大的项目的时候才会出现该异常。

如果是在tomcat中出现这个问题,解决办法是在{tomcat_dir}/bin/catalina.bat中添加如下一行:

set CATALINA_OPTS=-server -Xms256m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m

java.lang.OutOfMemoryError: GC overhead limit exceeded

这个错误会出现在这个场景中:GC占用了多余98%(默认值)的CPU时间却只回收了少于2%(默认值)的堆空间。目的是为了让应用终止,给开发者机会去诊断问题。一般是应用程序在有限的内存上创建了大量的临时对象或者弱引用对象,从而导致该异常。虽然加大内存可以暂时解决这个问题,但是还是强烈建议去优化代码,后者更加有效。

首先,你可以关闭JVM这个默认的策略:

1 java -XX:-UseGCOverheadLimit JavaApp

其次,你也可以尝试去加大Heap Size:

1 java -Xmx512m JavaApp

注意:在修改Tomcat的catalina.bat(*.sh)中的内容时,网上有很多都是说直接修改JAVA_OPTS,按照Apache官方的说法是:

Note: Do not use JAVA_OPTS to specify memory limits. You do not need much memory for a small process that is used to stop Tomcat. Those settings belong to CATALINA_OPTS.

预防OutOfMemoryError从我做起

导致java.lang.OutOfMemoryError的根本原因是程序不健壮

圈起来,这句话是重点

怎么做?

1、尽早释放无用对象的引用

2、使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域

3、尽量少用静态变量,因为静态变量存放在永久代(方法区),永久代基本不参与垃圾回收

4、避免在循环中创建对象

5、开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。

windows环境中直接到jdk安装目录bin文件夹下双击jvisualvm.exe打开,或者在cmd下输入jvisualvm回车。查看更多信息

OutOfMemoryError异常的常见原因

更多jvm学习

jvm基础概念理解

jvm内存模型详解记录

jvm中的堆和栈(面试总结)

jvm类加载过程

免责声明:文章内容不代表本站立场,本站不对其内容的真实性、完整性、准确性给予任何担保、暗示和承诺,仅供读者参考,文章版权归原作者所有。如本文内容影响到您的合法权益(内容、图片等),请及时联系本站,我们会及时删除处理。

为您推荐

nodejs 整理记录

nodejs 整理记录

下载包 https://blog.csdn.net/m0_59878114/article/details/120274...
websocket测试html

websocket测试html

<!DOCTYPE html> <html> <head> <meta cha...
bigdemical两个数比较大小

bigdemical两个数比较大小

/*int result = bigdemical1.compareTo(bigdemical2) result = -...
Beetl2.7 中文文档

Beetl2.7 中文文档

Beetl目前版本是2.7.23,相对于其他java模板引擎,具有功能齐全,语法直观,性能超高,以及编写的模板容易维护等...
纯CSS实现多个便签在一行展示,拖动滚动

纯CSS实现多个便签在一行展示,拖动滚动

div <h2>请注意需要在移动端预览,PC端拖拽无效果</h2> <div class=...
返回顶部