码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-07-19 18:05:30      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

1,java堆溢出

    ?JAVA堆用于存储对象实例,只要不断的创建对象,保证GC Roots到对象直接有可达路径,避免垃圾回收机制清楚对象,那么对象数量叨叨一定程度后,会产生内存溢出异常。

    ?如下代码,限制Java堆大小为1024m,并且-Xms和-Xmx的参数相同,即不可扩展。同事在Run Configuration中增加VM 参数:

  1. -XX:+HeapDumpOnOutOfMemoryError

让虚拟机在出现内存溢出异常时,Dump出当前的内存堆转储快照。

  1. package com.jvm.exception;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class HeapSpaceException {
  5. public static void main(String[] args) {
  6. List<byte[]> byteList = new ArrayList<byte[]>();
  7. while(true){
  8. byteList.add(new byte[1024]);
  9. }
  10. }
  11. }

运行结果:

  1. java.lang.OutOfMemoryError: Java heap space
  2. Dumping heap to java_pid2783.hprof ...
  3. Heap dump file created [3795151132 bytes in 3.289 secs]
  4. Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  5. at com.jvm.exception.HeapSpaceException.main(HeapSpaceException.java:13)

内存中首先提示OutOfMemoryError,让后提升Java heap space。

    ?一般出现此类问题,可以采用内存分析工具,如Eclipse Memory Analyzer进行分析。

    ?如果内存泄露,则查看泄露对象到GC Roots的引用链,确定内存泄露位置。

    ?如果内存未泄露,则应当检查虚拟机的参数(-Xmx 和 -Xms)。

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

    ?由于HotSpot虚拟机并没有区分虚拟机栈和本地方法栈,因此对HotSpot来说,-Xoss(设置本地方法栈大小)参数存在,但实际是无效的。栈容量只能通过-Xss参数设定。虚拟机栈和本地方法栈,在Java虚拟机规范中定义了两种异常:

    ?-1,如果线程请求栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError异常。

    ?-2,如果虚拟机找扩展栈时无法申请到足够的内存空间,则抛出OutOfMmemoryError。

首先在单线程环境中,使用-Xss参数减少栈内存容量,抛出StackOverFlowError。

  1. package com.jvm.exception;
  2. /**
  3. * 默认-Xss参数
  4. * @author jinglongjun
  5. *
  6. */
  7. public class StackOverFlowError {
  8. private int stackLength = 1;
  9. public void stackLeak(){
  10. stackLength ++;
  11. stackLeak();
  12. }
  13. public static void main(String[] args) {
  14. StackOverFlowError sof = new StackOverFlowError();
  15. try{
  16. sof.stackLeak();
  17. }catch(Throwable e){
  18. System.out.println("stackLength : " + sof.stackLength);
  19. throw e;
  20. }
  21. }
  22. }

输出内容:

  1. stackLength : 10828
  2. Exception in thread "main" java.lang.StackOverflowError
  3. at com.jvm.exception.StackOverFlowError.stackLeak(StackOverFlowError.java:13)
  4. at com.jvm.exception.StackOverFlowError.stackLeak(StackOverFlowError.java:14)

单线程环境,定义大量本地变量,增大方法栈中本地变量表的长度。结果抛出StackOverFlowEoor时,输出的堆栈深度相应的缩小。

这种情况模拟了很久没有模拟出来。因为本文是参考《深入理解Java虚拟机》这本书的,书中也未给出例子。

在单线程下,总是抛出StackOverFlowError。

多线程模拟。

?建议不要尝试运行下面的代码。

建议不要尝试运行下面的代码。

建议不要尝试运行下面的代码。

  1. package com.jvm.exception;
  2. public class OutOfMemoryError {
  3. public void dontStop(){
  4. while(true){
  5. }
  6. }
  7. public void stackLengthThread(){
  8. while(true){
  9. Thread thread = new Thread(new Runnable() {
  10. @Override
  11. public void run() {
  12. dontStop();
  13. }
  14. });
  15. thread.start();
  16. }
  17. }
  18. public static void main(String[] args) {
  19. OutOfMemoryError oome = new OutOfMemoryError();
  20. oome.stackLengthThread();
  21. }
  22. }

以上代码会抛出:

    ?OutOfMemoryError。

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:

原文地址:http://blog.csdn.net/mergades/article/details/46956271

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!