JAVA虚拟机学习实践2-实践
来源:互联网 发布:黑客帝国动画版 知乎 编辑:程序博客网 时间:2024/05/21 02:20
OOM异常
Java堆溢出
Java堆用于存储对象实例,我们只有不断地创建对象,在对象数量达到最大堆的容量限制后就会产生举出异常。
代码:
public class HeapOOM {
static class OOMObiect {
}
public static void main(String[] args) {
List<OOMObiect> list = new ArrayList<OOMObiect>();
while (true) {
list.add(new OOMObiect());
}
}
}
将上述代码编码后,用C:\Users\ai-wanxy3\Desktop\java>java -Xmx20m -Xms20m -XX:+HeapDumpOnOutOfMemoryError HeapOOM执行代码,其中-Xmx设置Java堆最大20m,-Xms设置Java堆最小20m,-XX:+HeapDumpOnOutOfMemoryrror将内存溢出时的内存堆转存为快照以便进行事后分析,执行结果如图2-1
图2-1
Java堆异常时,首先出现"java.lang.OutOfMemoryError",然后后面紧跟"Java heap space",并生成dump文件。
要解决这个区域的问题,首先要通过内存分析工具,如ibm Heapanalyzer重点是确认内存中和对象是否都是必要的,也就是清楚认识到到底是内存溢出还是内存泄露。如果不存在泄露,也就是内存中的对象确实都还需要活着,就应该考虑增加Java堆的大小了,-Xmx设置最大值,-Xms设置最小值。
虚拟机栈和本地方法区溢出
关于虚拟机栈和本地方法区栈,在Java虚拟机规范中描述了两种异常:
1、如果线程请求的栈深度大于虚拟机允许的最大深度,将抛出StackOverflowError异常。
2、如果虚拟机在扩展栈深度时无法申请到足够多的内存,将抛出OutOfMemoryError异常。
在测试该内存区的异常时,使用-Xss参数减少栈内存的容量,将抛出StackOverflowError异常,代码如下:
private int stackLength = 1;
public void stackLeak() {
stackLength++;
int i = 0;
while (i < 10000) {
Object o = new Object();
i++;
}
stackLeak();
}
/**
* @param args
*/
public static void main(String[] args) throws Throwable{
// TODO Auto-generated method stub
JavaVMStackOF oom = new JavaVMStackOF();
try {
oom.stackLeak();
} catch (Throwable t) {
System.out.println("stack length:" + oom.stackLength);
throw t;
}
}
}
使用命令:java -Xss1k JavaVMStackOF,执行时将报错:
stack length:21042
Exception in thread "main" java.lang.StackOverflowError
at JavaVMStackOF.stackLeak(JavaVMStackOF.java:20)
出现StackOverflowError异常时有错误堆栈信息可以阅读,比较容易找到问题所在。而且使用虚拟机默认配置,栈深度在大多数情况下达到1000-2000是没有问题的,对正常的方法调用,完全没有问题。
运行时常量池溢出
常量池位位于方法区内,可以通过 -XX:PermSize和-XX:MaxPermSize限制方法区的大小,间接限制常量区的大小。
如果要向常量池中添加内容,最简单的方法是使用String.intern()方法:如果池中包含了一个等于此String对象的字符串,则返回这个对象,否则将此对象添加到常量池中,并且返回此对象的引用,代码如下:
import java.util.ArrayList;
import java.util.List;
/**
* @author ai-wanxy3
*
*/
public class ConstantPoolOOM {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> list = new ArrayList<String>();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
使用命令:java -XX:MaxPermSize=1m ConstantPoolOOM执行代码,得到如下错误信息:
Exception in thread "main" java.lang.OutofMenoryError: PerMGen space
方法区溢
方法区用于存放Class的相关信息,如类名,访问修饰符、常量池、属性描述、方法描述等,对这个区域的描述,思路是生成大量的类去填满这个区域,直接溢出。与测试常量池溢出时类似。方法区溢出是一种常见的内存溢出,一个类要被垃圾收集器回收,判断条件是相当苛刻的,特别是在经常动态生成大量Class文件的应用中,特别需要注意类的回收状况。
本机直接内存区溢
DirectMemory容量可通过-XX:MaxDirectMemorySize=128m指定,如果不指定,则默认与-Xmx(Java堆大小),通过减少直接内存的值,在测试时报OutofMemoryError错误。
- JAVA虚拟机学习实践2-实践
- JAVA虚拟机学习实践1-简介
- JAVA虚拟机学习实践-IBM HeapAnalyzer
- JAVA并发实践学习
- 学习java重在实践
- java并发实践学习
- java泛型学习和实践(2)
- Spring 2 学习实践
- H5实践学习-2
- 学习《Java程序设计实践教程》
- java并发编程实践学习
- 《深入java虚拟机--JVM高级特性与最佳实践》学习笔记(一) 编译自己的JDK
- [连载] 深入理解Java虚拟机(JVM高级特性与最佳实践) 学习笔记连载分享
- 《深入理解Java虚拟机——JVM高级特性与最佳实践》学习笔记——虚拟机类加载机制
- xen虚拟机安装实践
- Java实践
- 《深入java虚拟机--JVM高级特性与最佳实践》学习笔记(二) JAVA虚拟机运行时数据区
- 《深入理解Java虚拟机——JVM高级特性与最佳实践》学习笔记——Java类文件结构
- redis与spring集成--不使用spring-data-redis
- springmvc 自定义异常处理机制
- 循环队列之循环队列长度和头尾指针关系
- oracle下lag和lead分析函数
- python post提交json 返回json值
- JAVA虚拟机学习实践2-实践
- iOS9新特性之(OC及Swift)实现3D Touch
- String类练习讲解-统计字符串中出现连续字符的次数
- win apache配置虚拟目录
- leetcode上的Sort a linked list using insertion sort
- Android Studio中如何打JAR包
- java中instanceof关键字用法
- 解决点击laucher应用重启的解决方案
- 关于C#try catch异常捕获语句一点需要注意的地方