Java 内存溢出(java.lang.OutOfMemoryError)常见情况和总结

标签: OutOfMemoryError java  PermGen space
2770人阅读 评论(0) 收藏 举报
分类:
在解决java内存溢出问题之前,需要对jvm(java虚拟机)的内存管理有一定的认识。
jvm管理的内存大致包括三种不同类型的内存区域:Permanent Generation space(永久保存区域)、Heap space(堆区域)、Java Stacks(Java栈)。
其中永久保存区域主要存放Class(类)和Meta的信息,Class第一次被Load的时候被放入PermGen space区域,Class需要存储的内容主要包括方法和静态属性。
堆区域用来存放Class的实例(即对象),对象需要存储的内容主要是非静态属性。每次用new创建一个对象实例后,对象实例存储在堆区域中,这部分空间也被jvm的垃圾回收机制管理。
而Java栈跟大多数编程语言包括汇编语言的栈功能相似,主要基本类型变量以及方法的输入输出参数。Java程序的每个线程中都有一个独立的堆栈。
容易发生内存溢出问题的内存空间包括:Permanent Generation space和Heap space。

第一种OutOfMemoryError: PermGen space (1.8后更新为Metaspace,不存在)
PermSpace主要是存放静态的类信息和方法信息,静态的方法和变量,final标注的常量信息等。
发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generation space有关。解决这类问题有以下两种办法:
1. 增加java虚拟机中的XX:PermSize和XX:MaxPermSize参数的大小,其中XX:PermSize是初始永久保存区域大小,XX:MaxPermSize是最大永久保存区域大小。
如针对tomcat6.0,在catalina.sh 或catalina.bat文件中一系列环境变量名说明结束处(大约在70行左右) 增加一行:
JAVA_OPTS=" -XX:PermSize=64M -XX:MaxPermSize=128m"
2. 清理应用程序中web-inf/lib下的jar,如果tomcat部署了多个应用,很多应用都使用了相同的jar,可以将共同的jar移到tomcat共同的lib下,减少类的重复加载。

第二种OutOfMemoryError:  Java heap space
发生这种问题的原因是java虚拟机创建的对象太多,在进行垃圾回收之间,虚拟机分配的到堆内存空间已经用满了,与Heap space有关。解决这类问题有两种思路:
1. 检查代码中是否有死循环或递归调用。
   检查是否有大循环重复产生新对象实体。
   检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
   检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
2. 增加Java虚拟机中Xms(初始堆大小)和Xmx(最大堆大小)参数的大小。如:set JAVA_OPTS= -Xms256m -Xmx1024m

第三种OutOfMemoryError:unable to create new native thread  
在java应用中,有时候会出现这样的错误:OutOfMemoryError: unable to create new native thread.
这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。
那么是什么原因造成这种问题呢?  每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。 这500M内存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余下400M的可用内存里边我们最多也只能创建400个可用线程。  
这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。 给出一个有关能够创建线程的最大个数的估算公式:
  (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads  对于jdk1.5而言,假设操作系统保留120M内存: 
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~
380 threads1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads  对于栈大小为256KB的jdk1.4而言,  1.5GB allocated to JVM: ~1520 threads
1.0GB allocated to JVM: ~3520 threads   对于这个异常我们首先需要判断下,发生内存溢出时进程中到底都有什么样的线程,这些线程是否是应该存在的,是否可以通过优化来降低线程数; 另外一方面默认情况下java为每个线程分配的栈内存大小是1M,通常情况下,这1M的栈内存空间是足足够用了,因为在通常在栈上存放的只是基础类型的数据或者对象的引用,这些东西都不会占据太大的内存, 我们可以通过调整jvm参数,降低为每个线程分配的栈内存大小来解决问题,例如在jvm参数中添加-Xss128k将线程栈内存大小设置为128k。
查看评论

java内存溢出(ava.lang.OutOfMemoryError)解决方法

内存溢出的原因一般如下: 1.JVM内存过小,程序不够健壮,所以产生过多垃圾; 2.从数据库取出过多数据,内存中加载数据太庞大; 3.代码中存在死循环; 4.代码中循环产生过多重复的对象实体;...
  • JavaBoy0724
  • JavaBoy0724
  • 2017-03-15 11:27:12
  • 379

深入理解JVM02--Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结

1、Java堆溢出     Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存...
  • oChangWen
  • oChangWen
  • 2016-05-14 13:09:06
  • 1864

Java常见内存溢出异常分析

Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈,程序计数器,方法区等,而Hotspot jvm的实现中,将堆内存分为了三部分,新生代,老年代,持久带,其中持久带实现了规范中规定的方法区,而...
  • tianwei7518
  • tianwei7518
  • 2015-01-21 09:15:08
  • 1562

SSM框架项目中Caused by: java.lang.OutOfMemoryError: PermGen space

Caused by: java.lang.OutOfMemoryError: PermGen space  1.你首先应该去检查你的spring是否配置了监听器(注意不要将类名写错)   ...
  • dadaxiongdebaobao
  • dadaxiongdebaobao
  • 2016-09-02 11:54:02
  • 488

Java常见内存溢出(OOM)解决方案

1,         程序计数器 一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器。 2,         java栈 与程序计数器一样,java栈(虚拟机栈)也是线程私有的,其生命...
  • toto1297488504
  • toto1297488504
  • 2014-05-12 09:09:04
  • 2375

Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结

java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因:JVM内存过小、程序不严密,产生了过多的垃圾。 导致OutOfMem...
  • u013434493
  • u013434493
  • 2014-01-10 10:49:41
  • 403

JAVA内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结

java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产生该错误的原因大都出于以下原因: JVM内存过小、程序不严密,产生了过多的垃圾。 导致OutOfMem...
  • znb769525443
  • znb769525443
  • 2016-03-11 10:14:49
  • 284

ElasticSearch——Java 内存溢出

Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结 java.lang.OutOfMemoryError这个错误我相信大部分开发人员都有遇到过,产...
  • Shiyaru1314
  • Shiyaru1314
  • 2016-04-27 17:41:45
  • 5874

weblogic 内存溢出解决 java.lang.OutOfMemoryError: PermGen space

Exception in thread “[STANDBY] ExecuteThread: ‘4’ for queue: ‘weblogic.kernel.Default (self-tuning)’...
  • zhq426
  • zhq426
  • 2015-09-19 16:30:52
  • 9614

常见的内存溢出的三种情况

常见的内存溢出的三种情况: 1)JVM Heap(堆)溢出:java.lang.OutOfMemoryError: Java heap space JVM在启动的时候会自动设置JVM Heap的值,...
  • wfg18801733667
  • wfg18801733667
  • 2017-02-28 11:16:10
  • 457
    个人资料
    专栏达人
    等级:
    访问量: 6万+
    积分: 1036
    排名: 4万+
    博客专栏
    最新评论
    文章存档