JAVA 内存溢出解析
核心提示:原因有很多种,比如: 1.数据量过于庞大;死循环 ;静态变量和静态方法过
多;递归;无法确定是否被引用的对象; 2.虚拟机不回收内存(内存泄漏); 说白了就
是程序运行要用到的内存大于虚拟机能提供的最大内存就发生内存溢出了。 内存溢出的问
题要看业务和系
原因有很多种,比如:
1.数据量过于庞大;死循环 ;静态变量和静态方法过多;递归;无法确定是否被引用的对
象;
2.虚拟机不回收内存(内存泄漏);
说白了就是程序运行要用到的内存大于虚拟机能提供的最大内存就发生内存溢出了。 内存
溢出的问题要看业务和系统大小而定,对于某些系统可能内存溢出不常见,但某些系统还
是很常见的解决的方法,
一个是优化程序代码,如果业务庞大,逻辑复杂,尽量减少全局变量的引用,让程序使用
完变量的时候释放该引用能够让垃圾回收器回收,释放资源。
二就是物理解决,增大物理内存,然后通过:-Xms256m -Xmx256m -
XX:MaxNewSize=256m -XX:MaxPermSize=256m 的修改
一、内存溢出类型
1 、 java.lang.OutOfMemoryError: PermGen space
JVM 管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在 JVM 启
动时创建;非堆是留给 JVM 自己用的,用来存放类的信息的。它和堆不同,运行期内 GC
不会释放空间。如果 web app 用了大量的第三方 jar 或者应用有太多的 class 文件而恰
好 MaxPermSize 设置较小,超出了也会导致这块内存的占用过多造成溢出,或者
tomcat 热部署时侯不会清理前面加载的环境,只会将 context 更改为新部署的,非堆存
的内容就会越来越多。
2 、 java.lang.OutOfMemoryError: Java heap space
第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间 ( 即 -Xms) 是
物理内存的 1/64 ,最大空间 (-Xmx) 是物理内存的 1/4 。如果内存剩余不到 40 %,
JVM 就会增大堆到 Xmx 设置的值,内存剩余超过 70 %, JVM 就会减小堆到 Xms 设置
的值。所以服务器的 Xmx 和 Xms 设置一般应该设置相同避免每次 GC 后都要调整虚拟
机堆的大小。假设物理内存无限大,那么 JVM 内存的最大值跟操作系统有关,一般 32 位
机是 1.5g 到 3g 之间,而 64 位的就不会有限制了。
注意:如果 Xms 超过了 Xmx 值,或者堆最大值和非堆最大值的总和超过了物理内存或
者操作系统的最大限制都会引起服务器启动不起来。
垃圾回收 GC 的角色
JVM 调用 GC 的频度还是很高的,主要两种情况下进行垃圾回收:
当应用程序线程空闲;另一个是 java 内存堆不足时,会不断调用 GC ,若连续回收都解
决不了内存堆不足的问题时,就会报 out of memory 错误。因为这个异常根据系统运行
环境决定,所以无法预期它何时出现。
根据 GC 的机制,程序的运行会引起系统运行环境的变化,增加 GC 的触发机会。