深入理解Java虚拟机读书笔记 一
走进Java
JDK包括 JAVA程序设计语言,JAVA虚拟机,JAVA API类库三部分.
Java内存区域与内存溢出异常
1.Java内存区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为5个区域.
1.1程序计数器.
程序计数器. 是一块较小的内存空间,可以看做当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是通过改变计数器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能都需要以来这个计数器来完成.
1.2Java虚拟机栈
Java虚拟机栈. 和程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同.虚拟机栈描述的是Java方法被执行的时候都会同时创建一个栈帧用于存储局部变量表,操作栈,动态链接,方法出口等信息.每一个方法被调用直至执行完成的过程,就对应一个栈帧在虚拟机栈中从入栈到出栈的过程.
局部变量表存放了编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用和returnAddress类型.
局部变量表所需的内存空间在编译期间完成分配
Java虚拟机规范中,对这个区域规定了两种异常情况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverFlowError异常;如果虚拟机栈可以动态拓展,当拓展是无法申请到做够的内存时会抛出OutOfMemoryError异常.
1.3本地方法栈
本地方法栈. 本地方法栈与虚拟机栈发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则是为虚拟机使用到的Native方法服务.虚拟机规范中对本地方法栈中的方法使用的语言,使用方式与数据结构没有强制规定,因此具体的虚拟机可以自由实现它.甚至有的虚拟机直接把本地方法栈和虚拟机栈合二为一.
1.4Java堆
Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域唯一的目的就是存放对象实例.
Java堆是垃圾收集器管理的主要区域,因此很多时候也被称做"GC堆".如果从内存回收的角度看,授予现在收集器基本都是采用分带收集算法,所以Java对中还可以细分为:新生代和老年带;在细致一点的有Eden空间,From Survivor空间,To Survivor空间等.
Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可.如果在堆中没有内存完成实例分配,并且对也无法在拓展时,将会抛出OutOfMemoryError异常.
1.5方法区
方法区. 方法区和堆一样,是各个线程共享的内存区域,它用于存储也被虚拟机加载的类信息,常量,常态变量,即时编译器编译后的代码等数据.虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫Non-Heap(非堆),目的应该是与Java堆区分开来.
1.6运行时常量池
运行时常量池. 是方法区的一部分.Class文件除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池.用于存放编译期生成的各种字面量和符号引用,这部分内容将在加载后存放到方法区的运行时常量池中.
1.7直接内存
直接内存. 并不是虚拟机运行时数据区的一部分.