Java虚拟机学习笔记

视屏网址:

https://www.365yg.com/a6501513115182563854#mid=7002701897

一、走进JVM

    JVM一般由器、方法区、java堆、java拟栈PC程序数器、本地方法行引擎等成。

二、运行时数据区域

Java虚拟机学习笔记

2.1 概念:

2.1.1程序计数器

       程序计数器是一块较小的内存空间,线程私有,主要用于指示当前字节码执行的行号。如果线程正在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码的地址,如果现在正在执行Native方法,此时计数器值为空(undefined)。此区域是唯一一个java虚拟机规范中没有OutOfMemoryError的区域。

2.1.2 Java虚拟机栈

(1)栈说明:

       与程序计数器一样,java虚拟机栈也是线程私有的,他的生命  周期和线程相同。虚拟机栈描述的是java的内存模型:每个方法被执行时都会创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息,方法的执行过程就是入栈和出栈的过程。

(2)局部变量表:

      存放编译时可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用和returnAddress类型(指向一条字节码指令的地址)。

注意:局部变量表所需要的内存空间在编译时期就完全确定了,在方法运行时期不再改变。

(3)异常情况:

         在java虚拟规范中,对这个区域规定了两种异常状态。如果线程请求的栈深度大于虚拟机允许的深度,将抛出StackOverflowError如果虚拟机栈可以动态扩张,当扩张时无法申请到足够的内存时会抛出OutOfMemoryError异常。

2.1.3本地方法栈

      本地方法栈与虚拟机栈所发挥的作用非常类似。其区别在于虚拟机栈为虚拟机执行java方法服务,而本地方法栈为虚拟机使用navtive方法服务。

2.1.4 Java堆

       Java堆是Java虚拟机所管辖的内存最大的一块。Java堆是被所有线程共享的。该区域唯一的目的就是存放对象实例。Java堆是垃圾回收管理的主要区域,所以也叫GC堆。因此java堆可细分为:新生代和老年代(Eden空间、From Survivor空间、To Survivor空间等)

2.1.5方法区

       方法区主要用于存储被java虚拟机加载的类信息、常量、静态变量、即编译器编译后的代码等数据。Java虚拟机对这个范围的限制非常宽松,可以选择不实现垃圾回收。但是并非数据进入了方法区就如永久代的名字一样,永久存在。这个区域的回收主要是针对常量池的回收和对类的卸载。

2.2 对象访问

不同虚拟机实现对象的访问方式不同,主流的有两种:使用句柄访问和直接指针访问。

1、使用句柄访问:

       java堆中会划分出一块内存来作为句柄池,java栈(reference)中存储的的是对象的句柄地址,而句柄中包含来对象实例数据和类型数据各自的具体地址信息。

2、直接指针访问

        若使用直接访问方式,java堆对象的布局中就必须考虑如何放置访问类型数据和相关信息,reference中直接存在的是对象的地址。

句柄访问和直接指针访问的优缺点:

        句柄访问:使用句柄访问的最大优点是reference中存储的是稳定的句柄地址,在对象被移动时(垃圾收集时移动对象是非常普遍的行为)只会改变句柄中的实例数据指针,而reference本身不需要改变。

       直接指针访问:直接指针访问最大的特点就是速度快,它节省来指针定位的时间。由于对象的访问在java中非常频繁,因此该类开销积少成多也是也是非常客观的成本,现在sun HotSpot就是使用的第二种方式。

 

2.3  实战:OutOfMemoryError异常

2.3.1 java堆内存溢出

        获取heap dump的方式:

 

 

 

 

 

 

 

 

   

 

相关文章: