Java堆用于存储对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清楚这些对象,就会在对象数量到达最大堆的容量限制后产生内存溢出异常。

代码清单中限制Java堆的大小为20MB,不可扩展(将堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便时候进行分析。

在Eclipse中的Run Configurations页签中设置虚拟机参数如下图所示:

java上传文件的时候发现服务器满了 java上传文件内存溢出_Java

代码如下:package oom;

import java.util.ArrayList;
import java.util.List;
/**
* JAVA堆溢出
* @author Madison
* @date 2014-7-11
* VM Args: -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
*/
public class HeapOOM
{
static class OOMObject{}
public static void main(String[] args)
{
List list = new ArrayList();
while(true)
list.add(new OOMObject());
}
}

运行结果:

java.lang.OutOfMemoryError:Java Heap space
Dumping Heap to java_pid3404.hprof...
Heap dump file created[22045981 bytes in 0.663 secs]

Java堆内存的OOM异常是实际应用中最常见的内存溢出异常情况。出现Java堆内存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会进一步提示“Java Heap space”。

要解决这个区域的异常,一般的手段是首先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分析清楚到底是处理内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。

如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots的引用链。于是就能找到泄漏对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。

如果不存在内存泄漏,换句话说是内存中的对象确实还必须存活着,那就应当检查虚拟机的堆参数(-Xmx与-Xms),与机器物理内存对比是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。

以上是处理Java堆内存问题的简略思路,仅供参考!

欲知后事如何,且听下回分解