zoukankan      html  css  js  c++  java
  • JVM学习笔记三_异常初步

    Java堆溢出

    说明:Java堆用于存储对象实例,只要不断创建对象。且保证GC Roots到对象之间有可达的路径来避免垃圾回收机制来清除这些对象,那么在对象数量达到最大堆的容量限制之后就会产生内存溢出异常。

    重点:模拟不断创建对象简单,但是需要保证创建出来的对象不被GC掉。同样的,出错时可能的状况也是如此,就是对象被创建出但是未被及时回收。-Xms堆最小值 -Xmx堆最大值。

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

    抛出两种异常:

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

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

    说明:单线程的情况下,不论是栈帧太大还是虚拟机的栈内存太小,当内存无法正常分配时,都会抛出StackOverflowError异常。

          但是如果在使用多线程的情况下,会产生OutOfMemoryError异常。每个线程不断去创建线程,那么当到达上限是,就会抛出OutOfMemoryError异常。而且栈帧越大,线程上限将会越小。

       原因就是:操作系统对于每个进程,分配的内存都是有限制的。虚拟机参数控制了Java堆和方法区的内存的最大值。所以剩余内存为 进程分配的最大内存(M) 减去 最大堆的内存Xmx,再减去最大方法区的MaxPermSize,

       程序计数器内存很小可忽略。剩下的内存是由虚拟机栈和本地方法栈分得的。每个线程分配到的栈容量越大,那么可建立的线程数量就会很小,建立线程时就会越容易把内存耗尽。

    一般情况下 栈深度可以达到1000到2000。但是如果建立了过多的线程导致了内存溢出,在不能减少线程和使用64位虚拟机的情况下,只能通过减少最大堆和减少栈容量来换取更多线程。

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

     运行时常量池是方法区的一部分,在JDK1.6及以前的版本中,因为常量池分配在永久代中,我们可以通过-XX:PermSize和-XX:MaxPermSize来限制方法区大小,从而间接限制其中常量池的容量。

     代码如下:

    1 public static void main(String[] args) {
    2     List<String> list = new ArrayList<String>();
    3     int i = 1;
    4     while (true) {
    5         ist.add(String.valueOf(i++).intern());
    6     }
    7 }

    会抛出OutOfMemoryError异常。

    但是在JDK1.7以后,while循环会一直进行下去。

    方法区的用于存储Class相关的信息,比如类名、访问修饰符、常量池、字段描述、方法描述等。对于此区域的测试,可以产生大量的类去填满方法区,直到溢出。

  • 相关阅读:
    【面向对象-天龙八部】
    【面向对象-作业】
    【OOP】面向对象的程序开发
    nmcli命令详解(创建热点,连接wifi,管理连接等)
    构造函数&&继承8.1
    Set集合之TreeSet类
    Set集合之HashSet类
    HDFS上传数据的流程
    zookeeper的安装与配置
    hive介绍、安装配置、表操作基础知识适合小白学习
  • 原文地址:https://www.cnblogs.com/kawin/p/10017379.html
Copyright © 2011-2022 走看看