JVM之JAVA虚拟机运行时数据区

运行时数据区域
在这里插入图片描述在这里插入图片描述

程序计数器
1、内存空间小,线程私有。字节码解释器工作是就是通过改变这个计数器的值来选取下一条需要执行指令的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器完成
2、如果线程正在执行一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是 Native 方法,这个计数器的值则为 (Undefined)。此内存区域是唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。
JAVA虚拟机桟
1、作用于方法执行的一块java内存区域
栈调用遵循先进后出的原则
2、每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直到完成的过程都会对应一个栈帧在虚拟机中从入栈到出栈
3、局部变量表可存放的数据类型包括:
Boolean、byte、char、short、int、float、long、double以及对象引用类型(reference类型)和returnAddress类型(指向了一条字节码指令的地址)等。
4、如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常
递归调用中,会产生堆内存异常,(递归造成StackOverflowError 由于每允许一个方法将创建一个栈帧,栈帧创建太多无法继续申请到内存扩展)
Exception in thread “main” java.lang.StackOverflowError
在这里插入图片描述
StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。

本地方法栈
1、与java虚拟机栈相同,每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息,每一个方法从调用直到完成的过程都会对应一个栈帧在虚拟机中从入栈到出栈
2、 Java虚拟机栈执行的时JAVA方法会被编译为字节码,本地方法栈执行的是native方法(调用其它语言时)
3、 区别于 Java 虚拟机栈的是,Java 虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。
JAVA堆
1、 它是JAVA内存区域中一块用来存放对象实例的区域,几乎所有的对象实例都在这里进行分配。
2、 JAVA堆是JAVA虚拟机中管理的内存中最大的一块,并且JAVA堆是被所有线程共享的一块内存区域
3、 JAVA堆可分为新生代和老年代 新生代可分为Eden、From Space、To Space
4、 JAVA堆是垃圾收集器管理的主要区域,因此很多时候也被称之为“GC 堆”
5、堆内存溢出
在这里插入图片描述
方法区
1、 属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
JAVA虚拟机运行时数据区的存储内容
在这里插入图片描述
运行时常量池
1、属于方法区一部分,用于存放编译期生成的各种字面量和符号引用。编译器和运行期(String 的 intern() )都可以将常量放入池中。内存有限,无法申请时抛出 OutOfMemoryError
对象的访问
1、 句柄访问
Java堆中划出一块内存作为句柄池,引用中存储对象的句柄地址,句柄中包含对象实例数据、类型数据的地址信息
引用中存储的是稳定的句柄地址,在对象被移动时只需要改变句柄池中句柄的实例数据的指针,而不需要改动栈中引用地址本身(垃圾收集时需要移动对象到不同的区域)
在这里插入图片描述

2、 直接指针
与直接指针不同的是,引用中存储的是对象的实例数据,实例数据中包含类型数据的地址
优势是速度快,相比较句柄减少了一次指针定位的时间开销,JVM HotSpot就采用这种方式
在这里插入图片描述

GC的概念
GC:Garbage Collection 垃圾收集。这里所谓的垃圾指的是在系统运行过程当中所产生的一些无用的对象,这些对象占据着一定的内存空间,如果长期不被释放,可能导致OOM(堆溢出)。内存区域中的程序计数器、虚拟机栈、本地方法栈这3个区域随着线程而生,线程而灭;栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈的操作,每个栈帧中分配多少内存基本是在类结构确定下来时就已知的。在这几个区域不需要过多考虑回收的问题,因为方法结束或者线程结束时,内存自然就跟着回收了。而Java堆和方法区则不同,一个接口中的多个实现类需要的内存可能不同,一个方法中的多个分支需要的内存也可能不一样,只有在程序处于运行期间时才能知道会创建哪些对象,这部分内存的分配和回收都是动态的,GC关注的也是这部分内存,如果涉及到“内存”分配与回收也仅指着一部分内存
回收算法
引用计数算法:(老牌垃圾回收算法。无法处理循环引用,没有被Java采纳)
1、引用计数算法的概念:
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
在这里插入图片描述

上面的3个图中,对于最右边的那张图而言:循环引用的计数器都不为0,但是他们对于根对象都已经不可达了,但是无法释放。

public class Object {
 
    Object field = null;
    
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            public void run() {
                Object objectA = new Object();
                Object objectB = new Object();//位置1
                objectA.field = objectB;
                objectB.field = objectA;//位置2
                //to do something
                objectA = null;
                objectB = null;//位置3
            }
        });
        thread.start();
        while (true);
    }

上方代码看起来有点刻意为之,但其实在实际编程过程当中,是经常出现的,比如两个一对一关系的数据库对象,各自保持着对方的引用。最后一个无限循环只是为了保持JVM不退出,没什么实际意义。
代码解释:代码中标注了1、2、3三个数字,当位置1的语句执行完以后,两个对象的引用计数全部为1。当位置2的语句执行完以后,两个对象的引用计数就全部变成了2。当位置3的语句执行完以后,也就是将二者全部归为空值以后,二者的引用计数仍然为1。根据引用计数算法的回收规则,引用计数没有归0的时候是不会被回收的。
对于现在使用的GC来说,当thread线程运行结束后,会将objectA和objectB全部作为待回收的对象。而如果我们的GC采用上面所说的引用计数算法,则这两个对象永远不会被回收,即便我们在使用后显示的将对象归为空值也毫无作用。
根搜索算法
1、根搜索算法的概念:
  由于引用计数算法的缺陷,所以JVM一般会采用一种新的算法,叫做根搜索算法。它的处理方式就是,设立若干种根对象,当任何一个根对象到某一个对象均不可达时,则认为这个对象是可以被回收的。
在这里插入图片描述
如上图所示,ObjectD和ObjectE是互相关联的,但是由于GC roots到这两个对象不可达,所以最终D和E还是会被当做GC的对象,上图若是采用引用计数法,则A-E五个对象都不会被回收。

2、可达性分析:
设立若干种根对象,当任何一个根对象到某一个对象均不可达时,则认为这个对象是可以被回收的。我们在后面介绍标记-清理算法/标记整理算法时,也会一直强调从根节点开始,对所有可达对象做一次标记,那什么叫做可达呢?这里解释如下:
可达性分析:
  从根(GC Roots)的对象作为起始点,开始向下搜索,搜索所走过的路径称为“引用链”,当一个对象到GC Roots没有任何引用链相连(用图论的概念来讲,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。
3、根(GC Roots):
说到GC roots(GC根),在JAVA语言中,可以当做GC roots的对象有以下几种:
1、栈(栈帧中的本地变量表)中引用的对象。
2、方法区中的静态成员。
3、方法区中的常量引用的对象(全局变量)
4、本地方法栈中JNI(一般说的Native方法)引用的对象。
注:第一和第四种都是指的方法的本地变量表,第二种表达的意思比较清晰,第三种主要指的是声明为final的常量值。在根搜索算法的基础上,现代虚拟机的实现当中,垃圾搜集的算法主要有三种,分别是标记-清除算法、复制算法、标记-整理算法。这三种算法都扩充了根搜索算法。

发布了10 篇原创文章 · 获赞 0 · 访问量 101

猜你喜欢

转载自blog.csdn.net/xiaobao1352/article/details/104205818
今日推荐