您的位置:首页 > 编程语言 > Java开发

Java内存区域与内存溢出异常

2018-04-18 16:16 281 查看

Java内存区域与内存溢出异常

运行时数据区域



程序计数器

记录当前线程执行的字节码的行号(指令地址)

线程私有

唯一一个没有规定任何OutOfMemoryError的区域

Java虚拟机栈

线程私有

Java方法执行的内存模型:方法执行时,会创建一个栈帧,存储局部变量表、操作数栈、动态链接、方法出口等信息。

我们平时说的“栈内存”,是指Java虚拟机栈中的局部变量表。变量局部表存储基本数据类型、对象引用类型。

两种异常

线程请求的栈深度大于虚拟机所允许的深度,抛出StackOverflowError异常

虚拟机栈动态扩展时,无法申请到足够的内存,抛出OutOfMemoryError异常

本地方法栈

虚拟机栈为虚拟机执行Java方法服务

本地方法栈为虚拟机使用到的Native方法服务,作用于虚拟机栈相似

抛出StackOverflowError和OutOfMemoryError异常

Java堆

所有线程共享,存放对象实例

堆内没有内存完成实例分配,并且堆也无法扩展时,抛出OutOfMemoryError异常

方法区

所有线程共享

存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常

OutOfMemoryError异常

Java堆溢出

代码

public class HeapOOM {
static class OOMObject {

}

public static void main(String[] args) {
List<OOMObject> list = new ArrayList<>();
while (true) {
list.add(new OOMObject());
}
}
}


设置虚拟机参数
-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\xxx\Desktop


异常如下
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
Heap dump file created [28207505 bytes in 0.158 secs]
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at HeapOOM.main(HeapOOM.java:15)


分析异常

将dump下来的堆转储快照文件导入Eclipse Memory Analyzer工具

点击Histogram查看类对象占用的空间大小,如下



程序通过不断的创建OOMObject对象,导致堆被迅速的占满,从而出现堆内存溢出

虚拟机栈和本地方法栈溢出

代码

public class JavaVMStackSOF {
private int stackLength = 1;

public void stackLeak() {
stackLength++;
stackLeak();
}

public static void main(String[] args) {
JavaVMStackSOF oom = new JavaVMStackSOF();
try {
oom.stackLeak();
} catch (Exception e) {
System.out.println("stack length:" + oom.stackLength);
e.printStackTrace();
}
}
}


虚拟机参数:
-Xss128k


异常如下

Exception in thread "main" java.lang.StackOverflowError
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:8)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:9)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:9)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:9)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:9)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:9)
........


方法区和运行时常量池溢出

代码

public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
}


虚拟机参数:
-Xms10m -Xmx10m


异常如下

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.Integer.toString(Integer.java:403)
at java.lang.String.valueOf(String.java:3099)
at RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:12)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: