java虚拟机与运行时库,java虚拟机运行时数据区

java虚拟机运行时数据区总结了一张图片,方便记忆:

A165429475-92081.jpg_small.jpg

OutOfMemoryError异常:

1.java堆溢出

测试:java堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免自动扩展,然后不停的创建对象。

结果:java.lang.OutOfMemoryError:Java heap space...

2.运行时常量池溢出

测试:通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,从而间接限制了常量池的容量,然后通过String类的intern()方法来填充常量池。

结果:java.lang.OutOfMemoryError:PermGen space

3.方法区溢出

测试:同上通过-XX:PermSize和-XX:MaxPermSize限制方法区的大小,然后借助CGLib直接操作字节码运行时,生成大量的动态类。

结果:java.lang.OutOfMemoryError:PermGen space

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

测试:栈容量是由-Xss参数设定

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError

如果虚拟机在扩展栈时无法申请到足够的内存空间则抛出OutOfMemoryError

/**

* VM Args:-Xss128k

*

* @author ksfzhaohui

*

*/

public class JavaVMStackSOF {

private static Log logger = LogFactory.getLog(JavaVMStackSOF.class);

private int stackLength = 1;

public void stackLeak() {

stackLength++;

stackLeak();

}

public static void main(String[] args) {

JavaVMStackSOF oom = new JavaVMStackSOF();

try {

oom.stackLeak();

} catch (Throwable e) {

logger.info("stack length:" + oom.stackLength);

logger.error(e);

}

}

}

在单个线程下,无论是由于栈帧太大,还是虚拟机栈容量太小,当内存无法分配是,虚拟机都抛出StackOverflowError。

如果测试不限于单线程,通过不断的建立线程的方式倒是可以产生OutOfMemoryError

/**

* VM Args:-Xss2M

*

* @author ksfzhaohui

*

*/

public class JavaVMStackOOM {

private void dontStop() {

while (true) {

}

}

public void stackLeakByThread() {

while (true) {

Thread thread = new Thread(new Runnable() {

@Override

public void run() {

dontStop();

}

});

thread.start();

}

}

public static void main(String[] args) throws Throwable {

JavaVMStackOOM oom = new JavaVMStackOOM();

oom.stackLeakByThread();

}

}

5.本机直接内存溢出

测试:通过-XX:MaxDirectMemorySize直接内存,通过ByteBuffer.allocateDirect方法分配内存,查看DirectByteBuffer类,其实内部真正分配内存的是UnSafe类

/**

* -Xmx20m -Xms20m -XX:MaxDirectMemorySize=10m

*

* @author ksfzhaohui

*

*/

public class DirectMemoryOOM {

private static final int _1MB = 1024 * 1024;

public static void main(String[] args) throws IllegalArgumentException,

IllegalAccessException {

Field unsafeField = Unsafe.class.getDeclaredFields()[0];

unsafeField.setAccessible(true);

Unsafe unsafe = (Unsafe) unsafeField.get(null);

while (true) {

unsafe.allocateMemory(_1MB);

}

}

} 结果:

java.lang.OutOfMemoryError

参考:深入java虚拟机

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值