深入理解Java虚拟机阅读心得(二)

垃圾收集

  程序计数器、虚拟机栈、本地方法栈三个区域随线程而生,随线程而灭;这几个区域的内存分配和回收都具备稳定性,不需要过多的考虑回收的问题。而Java堆和方法区则不一样。

  Java堆中存储了几乎所有的对象实例,垃圾收集器进行对堆的回收之前,需要判断这些对象是否还存活

一。判断对象是否存活

  判断对象是否还活着,主要有两种方法

  1.引用计数法

    给对象添加一个引用计数器,每当一个地方引用时,计数器值加1;

    每当一个引用失效时,计数器减1;

    任何计数器为0的对象为不可能被使用的对象。

    

    优点:实现简单,判定效率高

    缺点:很难解决对象之间的相互循环引用的问题

  2.可达性分析法

    主流的实现中,都是通过可达性分析法来判定对象是否存活。

    该算法基本思想:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链;

            当一个对象到GC Roots没有任何引用链相连时(即GC Roots无法到达该对象),称为不可达对象,该对象不可用

            此时,可以判定该对象是可回收的对象。

    Java中可以作为GC Roots的对象包括以下四种:

            (1)虚拟机栈中引用的对象

            (2)方法区中类静态属性引用的对象

            (3)方法区中常量引用的对象

            (4)本地方法栈中JNI(一般说的是Native方法)引用的对象

  3.方法区的回收

    由于方法区中主要存放的是永久代对象,因此,方法区中进行垃圾收集的性价比一般较低。

    永久代的垃圾回收主要分为两类:1.废弃常量   2.无用的类

    类的卸载条件比较苛刻,需要同时满足以下三个条件:

      (1)该类的所有实例已经被回收,即Java堆中不存在该类的任何实例

      (2)加载该类的ClassLoader(即类加载器)已被回收

      (3)该类对应的java.lang.Class对象没有在任何地方呗引用,无法在任何地方通过反射访问该类的方法

    在大量使用动态代理、反射的场景,需要虚拟机具备卸载类的功能,以保证永久代不会造成内存溢出

    

  4.finalize()

    类似 C++ 的析构函数,用于关闭外部资源。

    但 try-finally 等方式可以做得更好,并且该方法运行代价很高,不确定性大,无法保证各个对象的调用顺序,因此最好不要使用。

    当一个对象可被回收时,且被判定为有必要执行该对象的 finalize() 方法,那么可能让该对象自救(只需要重新与引用链上的任何一个对象建立关系即可)。

    自救只能进行一次,如果回收的对象之前调用了 finalize() 方法自救,后面回收时不会再调用该方法。

二。强引用与软引用

  Java对引用的概念分为四种,从强到弱依次为:强引用,软引用,弱引用,虚引用

  1.强引用

    代码中普遍存在的类似 Object obj = new Object()这种,只要强引用在,该对象永远不会被回收

  

  2.软引用

    用来描述一些还有用但非必须的对象;提供了SoftReference类来实现软引用

    在系统发生内存溢出异常之前,会把这些对象列入回收范围之中,进行第二次回收

  3.弱引用

    也是用来描述非必须对象,但是比软引用更弱;提供了WeakReference类来实现

    弱引用关联的对象,只能生存到下一次垃圾收集发生之前。

    当垃圾收集器工作时,无论当前内存是否足够,都会回收掉只被弱引用关联的对象。

  4.虚引用

    最弱的引用关系;提供PhantomReference类实现

    一个对象是否有虚引用的存在完全不会对其生存时间产生影响,同时也无法通过虚引用来取得一个对象的实例。

    设置虚引用的唯一目的是,通过虚引用在这个对象被回收时收到一个系统通知

原文地址:https://www.cnblogs.com/xiang9286/p/10542874.html

时间: 2024-07-31 21:08:56

深入理解Java虚拟机阅读心得(二)的相关文章

深入理解java虚拟机系列(二):垃圾收集器与内存分配策略

第一篇,点这里  深入理解java虚拟机系列(一):java内存区域与内存溢出异常 先直接上结构图,笔记下一次补上,结构图如下:

[深入理解Java虚拟机]<阅读笔记>

Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就需要了解一些底层的知识来进行错误排查. 自动内存管理机制:介绍内存是如何划分的. 垃圾收集器与内存分配策略:分析垃圾收集算法. 虚拟机性能监控与故障处理工具 调优案例分析与实战 第三部分:虚拟机执行子系统 类文件系统:介绍Class文件结构的各个组成部分. 虚拟机类加载机制:介绍类加载过程的各个阶段

深入理解Java 虚拟机阅读笔记(一)

1.程序计数器- 占用空间:较小 作用:字节码行号指示器 作用详情:指示指令执行,如(字节码的执行,分支,循环,跳转,异常处理,线程恢复) 特点:线程私有(每个计数器独立计算,上下文相互独立). 2.虚拟机栈 占用空间:依据栈空间设定 作用:java 方法执行的内存模型. 作用详情:每个方法执行时都会创建栈桢.用于储存局部变量表.栈操作数.动态链接.方法出口等信息.每个方法从调用到执行完成就对应一个栈帧在虚拟机栈中入栈到出栈的过程 特点:线程私有 3.本地方法栈 本地方法栈(Native Met

深入理解java虚拟机(十二) Java 语法糖背后的真相

语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言的功能产生任何影响,却能使程序员更方便的使用语言开发程序,同时增强程序代码的可读性,避免出错的机会.但是如果只是大量添加和使用语法糖,却不去了解他,容易产生过度依赖,从而无法看清语法糖的糖衣背后,程序代码的真实面目. 总而言之,语法糖可以看做是编译器实现的一些"小把戏",这些"小

深入理解Java虚拟机之垃圾收集二

垃圾收集器 图示为JDK1.7 Update14之后的HotSpot虚拟机所使用的所有垃圾收集器. 如果两个收集器存在连线,那么说明这两个收集器可以搭配使用.收集器所处的区域说明它是新生代收集器还是老年代收集器. Serial收集器 主要看图↑ 上图演示了Serial/Serial Old收集器运行示意图. Serial收集器是一个单线程收集器,该收集器在进行垃圾收集的同时,必须暂停(Stop the World!)其它工作线程(这就好比你妈妈在打扫房间的同时,肯定也会让你乖乖待在一边,如果她一

深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种:

深度理解java虚拟机读书笔记(二)HotSpot Java对象创建,内存布局以及访问方式

内存中对象的创建.对象的结构以及访问方式. 一.对象的创建 在语言层面上,对象的创建只不过是一个new关键字而已,那么在虚拟机中又是一个怎样的过程呢? (一)判断类是否加载.虚拟机遇到一条new指令的时候,首先会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号代表的类是否被加载.解析并初始化.如果没有完成这个过程,则必须执行相应类的加载. (二)在堆上为对象分配空间.对象需要的空间大小在类加载完成后便能确定.之后便是在堆上为该对象分配固定大小的空间.分配的方式也有两种:

深入理解java虚拟机系列(一):java内存区域与内存溢出异常

文章主要是阅读<深入理解java虚拟机:JVM高级特性与最佳实践>第二章:Java内存区域与内存溢出异常 的一些笔记以及概括. 好了开始.如果有什么错误或者遗漏,欢迎指出. 一.概述 先上一张图 这张图主要列出了Java虚拟机管理的内存的几个区域. 常有人把Java内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java内存区域的划分实际上远比这复杂,从上图就可以看出了.堆栈分法中所指的"栈"实际上只是虚拟机栈,或者说是虚拟机栈中的局部变量表部分.接下

《深入理解Java虚拟机》读书笔记---第一章 走进Java

一.为什么要读此书 <深入理解Java虚拟机>这本书读了很多次,每次读都会有不一样的感受.首先说一下为什么要读这本书,如果把Java比喻成乾坤大挪移,那了解虚拟机的工作原理就是练习九阳神功,java语言是招式,对虚拟机的认识是内功心法,只有内功心法强大,所使的招式才强大,这就是为什么阳顶天只能把乾坤大挪移练到第四层,而张无忌能练到第七层.由于java虚拟机的强大,把很多功能都隐藏了,例如内容管理,垃圾回收机制等,使得很多java程序猿对这一块的知识所有缺失,编码的时候也是似懂非懂的,以至于遇到