《深入理解JAVA虚拟机》--第二章 Java内存溢出异常

1,Java堆溢出

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

解决

public class HeapOOM {

  static class OOMObject {
  }

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

   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]

a,内存泄露

通过工具查看泄露对象到GC Roots的引用链。,垃圾收集器无法自动回收对象了

b,内存溢出

检查虚拟机堆参数,是否可以调大

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

HotSpot虚拟机中不区分虚拟机栈和本地方法栈

public class JavaVMStackSOF {

  private int stackLength = 1;

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

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

stack length:2402
Exception in thread "main" java.lang.StackOverflowError
        at org.fenixsoft.oom.VMStackSOF.leak(VMStackSOF.java:20)
        at org.fenixsoft.oom.VMStackSOF.leak(VMStackSOF.java:21)
        at org.fenixsoft.oom.VMStackSOF.leak(VMStackSOF.java:21) 


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

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

3,运行是常量池溢出

向运行时常量池中不断添加内容

public class RuntimeConstantPoolOOM {

  public static void main(String[] args) {
  // 使用List保持着常量池引用,避免Full GC回收常量池行为
  List<String> list = new ArrayList<String>();
  // 10MB的PermSize在integer范围内足够产生OOM了
  int i = 0;
  while (true) {
  list.add(String.valueOf(i++).intern());
  }
  }
} 

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at org.fenixsoft.oom.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:18) 

4,方法区溢出

方法区用于存放Class的相关信息,如类名,访问修饰符,常量池,字段描述,方法描述等。

思路:运行时产生大量的类去填满方法区,直到溢出

public class JavaMethodAreaOOM {

  public static void main(String[] args) {
   while (true) {
  Enhancer enhancer = new Enhancer();
  enhancer.setSuperclass(OOMObject.class);
  enhancer.setUseCache(false);
  enhancer.setCallback(new MethodInterceptor() {
  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
  return proxy.invokeSuper(obj, args);
  }
  });
  enhancer.create();
   }
  }

  static class OOMObject {

  }
} 

Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616) 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值