首页 > 其他分享 >JVM垃圾回收

JVM垃圾回收

时间:2023-01-28 19:56:41浏览次数:34  
标签:finalize 对象 回收 GC 垃圾 JVM 引用

一、如何判断对象可以回收?

  1. 引用计数法:只要一个对象被其他变量所引用,就让计数加一,引用两次就让计数变为2,取消引用就让计数减一,但是这种算法有严重的弊端,如果两个变量之间循环引用的话,他们永远无法被垃圾回收。

 

 

   2,可达性分析:通过一系列被称为「GC Roots」的根对象作为起始节点集,从这些节点开始,通过引用关系向下搜寻,搜寻走过的路径称为「引用链」,如果某个对象到GC Roots没有任何引用链相连,就说明该对象不可达,即可以被回收。

    垃圾回收时,JVM首先要找到所有的GC Roots,这个过程称作 「枚举根节点」 ,这个过程是需要暂停用户线程的,即触发STW。
然后再从GC Roots这些根节点向下搜寻,可达的对象就保留,不可达的对象就回收。

  

哪些对象可以作为GC Roots?

    1、方法区静态属性引用的对象

    2、方法区常量池引用的对象

    3、方法栈中栈帧本地变量表引用的对象

    4、本地方法栈中引用的对象

    5、被同步锁持有的对象

怎么查看根对象有哪些?

    可以用Eclipse推出的Memory Analyzer(MAT)工具,先通过jmap生成一个内存快照,然后用MAT工具去分析该快照

 

 

 

 

 二、引用类型:强软弱虚 + (终结器引用)

  强引用:平时用的都是强引用,如果A对象没有被GC root直接或间接的强引用,A对象就可以被垃圾回收

  软引用:如果A对象只被软引用所引用,如果下一次垃圾回收时发现内存仍然不够,就会把软引用引用的A对象也回收。

  弱引用:如果A对象只被弱引用所引用,在下一次垃圾回收时就会回收A对象

  虚引用:如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收,它不能单独使用也不能通过它访问对象,虚引用必须和引用队列(RefenenceQueue)联合使用。虚引用的主要作用是跟踪对象垃圾回收的状态。仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。

换句话说,设置虚引用的唯一目的,就是在这个对象被回收器回收的时候收到一个系统通知或者后续添加进一步的处理

  *终结器引用:和对象的finalize()方法有关,如果一个对象重写了finalize方法,虚拟机会给对象创建一个终结器引用,当对象第一次被垃圾回收的时候会把终结器引用放到引用队列中,再由一个优先级很低的线程,叫做finalize handler线程,在某些时机去查看引用队列中有没有终结器引用,有的话就会去调用对象的finalize()方法,执行完方法后,在下一次垃圾回收时才会把对象真正回收掉。

        这里可以发现finalize()的效率很低,第一次垃圾回收时不能把对象真正回收掉,而是把终结器放到引用队列,而且finalize handler的优先级很低,可能导致该对象的finalize()方法迟迟不被执行,对应内存也不能被回收。所以一般不推荐使用finalize()方法。

 

三、垃圾回收算法

  1,标记清楚算法: Mark Sweap

    第一步:先标记,根据GC Root扫面堆中对象,标记出没有被直接或间接引用的对象,可以被回收。

    第二步:后清除,将第一步标记的区域进行释放,*注意,这里释放不是指把每个区域的字节进行清零,而是把对象的起始和结束地址放到空闲地址列表中,下次分配新地址的时候就到空闲地址列表中去找有没有一块足够的空间容纳新对象。

    优点:速度快,只需要记录对象的起始和结束地址。

    缺点:没有整理工作,容易产生内存碎片。

 

  2,标记整理算法:Mark Compact

    第一步:和标记清除算法一样,标记出垃圾

    第二步:将剩余的存活对象进行整理,把可用的对象向前移动,使内存更为紧凑。

    优点:无内存碎片,有连续的内存空间可用

    缺点:由于牵扯对象的移动,地址变了,需要改变对象的引用地址,效率较低

 

  3,复制算法 Copy

    第一步:也是标记出未被引用的空间、

    第二步:将from中存活的空间移动到to中,清楚from中所有的空间

    第三步:将from和to的位置调换,to的空间始终空闲

    缺点:占用双倍的内存空间

    

 

 

 

 

 以上三种算法在JVM中都会用到,在实际中根据不同情况来采用。

 

 四、分代回收算法

新对象都会被存放在Eden区中,当Eden区满了会触发新生代GC(Minor GC),因为新生代中大多数对象的生命周期都很短,所以发生Minor GC的频率很高,虽然它会触发stop-the-world,但是它的回收速度很快。

每次Minor GC都把不需要回收和幸存区留下的采用复制算法移到To中,然后交换From和To的位置,记录每个对象的年龄,没被回收的话,年龄+1,如果一个对象经历了15次GC都没被回收,就会被放入老年代。*另外,如果幸存区空间紧张时,或者要存放一个大小超过幸存区的大对象,该对象会被直接存放在老年代。

如果新生代和老年代都接近满了,存不下新对象,就会触发Full GC,对新生代和老年代整个进行清理。

 

 

 

五,垃圾回收器

  5.1 分类:

     串行: 单线程,堆内存较小,适合个人电脑

     吞吐量优先: 多线程,堆内存较大,多核CPU,让单位时间内STW的时间最短 0.2,0.2 = 0.4

     相应时间优先:多线程,堆内存较大,多核CPU,尽可能让单次的STW时间最短 0.1,0.1,0.1,0.1,0.1 = 0.5

     

    

 

标签:finalize,对象,回收,GC,垃圾,JVM,引用
From: https://www.cnblogs.com/tyleaf/p/17071167.html

相关文章

  • Dotnet程序的内存与垃圾回收
    都知道程序运行时的变量是放在内存里的,从我们学c++就知道有析构函数 malloc,还有学c#的时候天天什么垃圾回收GC像背八股文样的,但是这个内存究竟能分配多少没有人想过......
  • Dotnet程序的内存与垃圾回收
    都知道程序运行时的变量是放在内存里的,从我们学c++就知道有析构函数 malloc,还有学c#的时候天天什么垃圾回收GC像背八股文样的,但是这个内存究竟能分配多少没有人想过......
  • 【已解决】Error: could not open `C:\Program Files\Java\jre1.8.0_121\lib\amd
    原因:java升级时,会在环境变量的path路径中增加以下两条路径,与我们安装java的路径重合。解决方法:删掉环境变量中的这两条语句,同时找到对应文件,删除即可。C:\ProgramData\O......
  • G1 垃圾收集器参数
    1.G1垃圾收集器是在1.74u版本加入(由Oracle加入),jdk1.8中默认的还是CMS垃圾收集器(CMS在jdk14中被废弃,在jdk11中),如果jdk8想使用G1收集器需要手动调参 ......
  • 精华推荐 | 【JVM深层系列】「GC底层调优系列」一文带你彻底加强夯实底层原理之GC垃圾
    前提介绍很多小伙伴,都跟我反馈,说自己总是对JVM这一块的学习和认识不够扎实也不够成熟,因为JVM的一些特性以及运作机制总是混淆以及不确定,导致面试和工作实战中出现了很多的纰......
  • synchronized加锁对象和JVM对锁的优化
    synchronized加锁对象对于普通同步方法,锁是调用该方法的对象。对于静态同步方法,锁是该方法所属类的Class对象。对于同步代码块,锁是synchronized括号里面的对象。JVM对锁......
  • JavaScript 内存管理及垃圾回收
    一、内存管理JavaScript是一种自动垃圾回收语言,这意味着JavaScript引擎会自动监测和清理无用的内存。JavaScript中的内存管理主要由JavaScript引擎负责,开发人员不......
  • GC垃圾回收
    GC垃圾回收GC(GarbageCollection):垃圾回收器,用于java堆的内存管理,在JVM中程序计数器,java虚拟机栈,本地方法栈的生命周期跟随线程,栈帧的进栈和出栈能够实现自动清理,jdk8......
  • JVM内存划分
    JVM内存划分概述java虚拟机(JavaVirtualMachine简称JVM):是运行所有java程序的抽象计算机,是java语言的运行环境。对于java语言来说,在虚拟机的自动内存管理机制的帮助......
  • python基础: 垃圾回收机制、字符编码、文件操作
    目录垃圾回收机制引用计数标记清除分代回收字符编码简介发展史字符编码的实操文件操作垃圾回收机制说明:我们在编写代码的时候涉及到存储空间的申请和存储空间的释放的操......