Java虚拟机——垃圾回收相关算法

1.将对象的释放和内存的回收的好处?
在Java编程中将这些工作交给虚拟机,简化了代码的同时也减轻了程序员的工作任务,自动化的垃圾回收以及内存管理带来很大的便利。但是当出现内存泄漏和内存溢出等情况时,很少程序员会对虚拟机的垃圾回收机制熟悉,并不是那么容易排查问题。因此了解虚拟机的原理还时有必要的。
2.垃圾回收器的算法
在Java堆中和方法区里面的对象时在运行时创建的,内存的回收也是动态的。因此在这些内存回收之前需要判断,里面的对象的哪些是活着的,哪些是“死去”的(不被任何途径的对象的引用)。
而这些判断方式就是我们垃圾回收器采用的算法,下面来一一介绍有哪些判断方式?以及为了更加准确判断又做了那些改进?
2.1引用计数算法
有一个计数器,当对象被引用时加1,当对象引用释放时减1,如果一个对象的计数为0时,就会被判定为可回收。但是这种方法有一个缺点,当对象之间相互引用,除此之外再无其他的任何引用时,就会被认为不可回收的。当然现在主流的虚拟机并没有使用这种算法来实现。而是使用的可达性分析算法来实现的。
2.2可达性分析算法
可达性分析是指对象是否能够跟GC root起始点有链接,如果不存在链接也就是不可达时,及时几个对象之间相互引用,也会被认为是可回收的。
那在虚拟机中GC root是如何选取的呢?哪些可作为GC root起始点呢
A.在虚拟机栈(帧栈的本地变量表)中对象引用
B.方法区中静态引用的对象
C.方法区中常量引用的对象
D.本地方法栈中引用的对象
2.3虚拟机如何发起内存回收问题?
前面我们了解到可达性分析,根据对象与GC root 是否有链接来判断是否回收对象,那虚拟机是通过分析遍历所有对象的吗?,这样一来效率就会降低。虚拟机实际的实现并非如此,虚拟机在类加载时使用OopMap数据结构计算出对象在什么偏移量上数据类型,并在特定位置中记录栈和寄存器引用的部分。
2.3.1安全点
虚拟机并没有为每个对象建立OopMap结构,不然会需要很大的内存消耗,而是在特定的位置建立OopMap,这些特殊的位置成为安全点,安全点的选取标准是根据是否可以让程序可长时间执行,比如:循环/方法调用/异常跳转
2.3.2安全区
当程序执行时,安全点是可以满足要求的,但对于未执行的线程是没有覆盖到。比如处于休眠的线程,因此拓展安全点的概念形成了安全区,对于未分配CPU执行时间的线程,添加安全区的标记,当线程运行到安全区时打上标记,发生GC时跳过这个区域,处于安全区的线程想要恢复运行时,需要检验GC root是否枚举完成或者GC结束,若未结束则继续等待,等待GC运行结束的信号。
安全区:程序中的一段代码,其中的数据引用不会发生变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值