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

1.运行时数据区:

程序计数器:
    作用:可以看做是当前线程所执行的字节码的行号指示器。字节码工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础的功能都需要依赖这个计数器来完成
 JAVA虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内存)只会执行一条线程中的指令。为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间扥计数器相互不影响,独立存储,这个类内存区域”线程私有“的内存。
虚拟机栈:
    虚拟机栈:(局部变量表)存放了编译器可知的各种各种数据类型(Boolean,byte,char,short,int,float,long,double),对象引用(reference类型,它不等同与对象本身,根据不同的虚拟机栈实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指定的地址)
    在JAVA虚拟机规范中,对于这个区域规定了俩种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的JAVA虚拟机都动态扩展,只不过JAVA虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常
本地方法栈:
    本地方法栈与虚拟机栈所发挥的作用类似,区别:虚拟机栈为虚拟机执行JAVA方法(也就是字节码)服务,本地方法栈则是为虚拟机使用到的Native方法服务。本地方法栈也会抛出:StackOverflowError和OutOfMemoryEorror异常
    Java堆:
    Java堆是来及收集器管理的主要区域,因此很多时候也被称为(GC堆)。内存回收的角度看:由于现在收集器基本都是采用的分代收集算法,所以JAVA堆中可以细分为:新生代和老年代;在细致点有Eden空间,From Survivor空间、To Survivor空间等。内存分配的角度看:线程共享的Java堆中可能换分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB);都是存储对象实例;
    虚拟机都是按照可扩展来实现的(通过-Xmx和-Xms控制);如果再对中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常
           方法区:方法区和Java堆一样,是各个线程共享的内存区域,他用于存储已经被虚拟机加载的类信息,常量,静态变量,及时编译器编译后的代码等数据。虽然Java虚拟机规范吧方法区描述为堆的一个逻辑部分,但是他却又一个别名叫做NON-Heap,目的:与JAVA堆分开
        运行时常量池(Runtime Constant Pool):是方法区的一部分,用于存放编译器生成的各种字面量和字符引用,这部分内容将在类加载后存放在方法区的运行时常量池中。
    
发布了33 篇原创文章 · 获赞 3 · 访问量 3万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章