首页 > 编程语言 >JVM垃圾回收机制之对象回收算法

JVM垃圾回收机制之对象回收算法

时间:2023-04-21 17:44:57浏览次数:37  
标签:对象 回收 算法 GC 引用 JVM 内存

在前面的文章中,介绍了JVM内存模型分为:堆区、虚拟机栈、方法区、本地方法区和程序计数器,其中堆区是JVM中最大的一块内存区域,在Java中的所有对象实例都保存在此区域,它能被所有线程共享。

在Java中还有一个重要的机制:GC(垃圾收集器),堆是GC管理的主要区域,本文会带大家了解GC机制。

GC的简介
GC(Garbage Collection)垃圾收集机制是Java一个重要特性。不同于C/C++语言需要程序员自己管理内存的回收,而且这样做往往容易出错,导致内存泄漏等严重问题。

Java程序员不用编写回收内存的代码,因为Java有GC机制,它是一个特殊的后台线程,该线程对JVM中的内存进行标记,并确定哪些需要回收,再通过一定的回收策略自动回收内存,它在后台一直运行,保证JVM不会出现内存溢出的问题。

对象回收的算法
那么GC是如何判断某个对象的内存需要回收呢?GC需要判断该对象已死,也就是不再被调用,如何判断对象不再被调用呢?

这里有两种算法:

1、引用计数算法

2、可达性分析算法

引用计数算法
该算法给每个对象分配一个计数器,当有引用指向这个对象时,计数器加1,当指向该对象的引用失效时,计数器减一。最后如果该对象的计数器为0时,java垃圾回收器会认为该对象是可回收的。

优点:

1、实时性高,只要对象计数器为0就进行回收,不用等到内存不足的时候。

2、在垃圾回收过程中,应用无需挂起。

3、更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

缺点:

1、每次引用对象时,都会更新计数器,有时间消耗

2、不能解决循环引用问题

那什么是循环引用问题呢?我们看下面这段代码:

上面的a、b两个对象虽然都赋值为null,但是都不能回收,因为存在循环引用,它们的计数器不为0.

可达性分析算法
该算法通过一种被称作“GC Root”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,则证明此对象时不可用的。

如下图:

 

在Java语言中,可作为GC Roots对象包括下面几种:

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

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

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

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

再回头看前面这段代码,虽然a和b对象的引用计数都不为0,但是它们作为GC Root对象,最后都赋值为null,导致引用不可达,这样两个对象都是可以被回收的。

 

总结
本文小千带我们学习了JVM中的垃圾收集(GC)机制,GC是一个在后台持续运行的线程,帮助我们回收JVM堆中的对象内存,保证JVM不会内存溢出。

如何判断对象内存需要回收,有两个算法:引用计数算法和可达性分析算法。

引用计数算法通过判断对象的引用计数为0,就标记该对象内存可以回收,但是不能很好的解决循环引用问题;可达性分析算法通过GC Root向下搜索,如果引用链相连则对象可达,否则标记对象不可达,可以进行回收,这种算法能很好解决对象循环引用问题。

标签:对象,回收,算法,GC,引用,JVM,内存
From: https://www.cnblogs.com/qian-fen/p/17341238.html

相关文章

  • Python用哈希算法查找相似图片(包括不同分辨率,不同大小,不同格式的图片)
    #-*-coding:utf-8-*-'''Python用哈希算法查找相似图片并放入[_df]的文件夹中相似图片包括不同分辨率,不同大小,不同格式,只要图片相似就会算重复文件安装cv2pipinstallopencv-python'''importosimportcv2importnumpyasnpimportshutilimportrandomclas......
  • 从原理聊JVM(一):染色标记和垃圾回收算法
    作者:京东科技 康志兴1JVM运行时内存划分1.1运行时数据区域•方法区属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。运行时常量池,属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用。JDK1.8之前,Hotspot虚拟机对......
  • Diffie-Hellman密钥交换算法
    目录前置知识密钥交换算法隐私计算常用到各种加密算法,那么双方如何协商得到同一个不被泄露的密钥呢?一种做法是基于RSA,拥有公钥的一方将随机私钥加密提供给对方,对方再利用私钥解密出密钥。于是双方都得到了会话密钥。上面这种基于非对称加密的方法是SSL最古老的密钥协商方式,早......
  • 牛顿迭代法求方程根(递归算法)
    #include<iostream>#include<cmath>usingnamespacestd;doublef_origianal(doublea,doubleb,doublec,doubled,doublenewx){ returna*pow(newx,3)+pow(newx,2)*b+c*newx+d;}doublef_after_or(doublea,doubleb,doublec,doubled,......
  • 十级NLPer才能笑出声的算法梗!
    文|付奶茶近期小编整理出了一些非常好笑的梗图,与各位NLPer共赏,希望与大家一起评选出本期最好笑的梗图选手!【1号选手:非常擅长讲笑话的NLM】前排评论区:(1)Ienjoyedyourjokeaboutjokeaboutjokeaboutjokeaboutjokeaboutjokeaboutjokeaboutjokeaboutjokeaboutlanguag......
  • 分析什么情况下回有大量的垃圾回收(GC)
    在前端性能监控中,大量的垃圾回收(GC)通常是由以下原因导致的:内存泄漏:当页面中的对象没有被正确地释放或引用计数错误时,会导致内存泄漏。当内存中的对象达到一定数量时,JavaScript引擎会执行垃圾回收以释放这些不再使用的对象,从而导致大量的GC。频繁的创建和销毁对象:如果页面......
  • 几何算法
    C++常用计算几何算法-小四的海市蜃楼-C++博客(cppblog.com)(59条消息)C++常用计算几何算法_计算几何常用算法c++_Belial_2010的博客-CSDN博客......
  • SQL JOIN的常见连接算法(转载)
    原文:https://zhuanlan.zhihu.com/p/495442432在数据库和大数据领域,通过SQL中的JOIN连接将两个及两个以上的表(或中间表、视图、物化视图)中的数据按指定的连接条件关联起来,是很常用也很方便的操作。我们前面学习了JOIN有多种常见连接方式如内连接INNERJOIN、左外连接LEFTJOIN等......
  • QuHai互联科技 算法题部分
    11、实现计算第n个斐波那契数12、给定一个字符串编码规则,如输入字符串”Y3E12S!3”,字母后面的数字表示该字符重复几次,如果字符后没有数字则表示一个字符,最终输出转码后的字符串’YYYEEEEEEEEEEEES!!!’。试写出转码的函数,编程语言不限。13、简述你所了解的两种或以上排序算法......
  • JVM中的编译器
    JVM中集成了两种编译器,ClientCompiler和ServerCompiler,它们的作用也不同。ClientCompiler注重启动速度和局部的优化,ServerCompiler则更加关注全局的优化,性能会更好,但由于会进行更多的全局分析,所以启动速度会变慢。两种编译器有着不同的应用场景,在虚拟机中同时发挥作用。Clien......