java垃圾回收机制-2021-11-15

java中GC机制

上一讲说到java堆中是垃圾回收的主要管理区域,本讲来具体讲解JVM的垃圾回收机制(以下部分内容来自深入理解JVM)

# 对象的结构与对象的内存分配方式

1、对象的内存结构
a、对象头(Header)

  1. 自身运行时数据(Mark Word)
    哈希值、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID等
  2. 类型指针
  3. 指向对象类型的指针,就是方法区中存储的哪个类

b、实例数据(Instance Data)
4. 基本数据类型(Longs doubles shorts…)
5. 引用数据类型
c、填充(Padding)
6. 计算机存储使对象的内存为8字节的整数倍,不够就填充
2、对象的内存分配方法
指针碰撞:针对于垃圾回收规整区域
在这里插入图片描述
原来空闲区域为实线左边,创建一个对象,分界线就移到了虚线那一块,实线与虚线为边界的区域就是对象的内存区域
空闲列表:不规整
通过列表来记录那些区域空闲,把对象放到空闲列表中空闲的地址区域,这里就存在一个问题就是多线程的话需要保证线程同步,否则当一个对象分配区域0X02,另一个线程创建对象也同时分配0X02,空闲列表还未更新,对象就被线程2修改。
谈谈ThreadLocal和Synchronized
ThreadLocal:通过创建对象本地副本,使得每个线程都是对不同的内存区域进行操作,使得线程可以并发同步进行,简单来说内存消耗增加,时间减小
synchronized:对变量加锁,使得每次都只有一个线程区访问,线程之间只能串行对变量进行操作,这里具体锁机制也会在后面提到
2、对象的访问方式

  1. 使用句柄

在这里插入图片描述
句柄含两个指针:堆中对象+方法区中对象类型
来自:https://blog.csdn.net/qq_16438883/article/details/103086386
2. 使用指针(没啥可讲)

## JVM的垃圾回收机制

1、回收什么
回收堆中没有引用指向的对象
2、怎么判断对象没有引用指向

  • 引用计数法
    当有引用指向对象,计数器就+1,引用失效就-1,在任何时刻计数器都为0就需要回收
    局限:
    当对象循环调用时候。
    在这里插入图片描述
    当a,b失效时,m1与m2也应该被回收
public class GCTest01 {
    public Object instance=null;
    private static int MB = 1024 * 1024;
    private byte[] bigSize = new byte[2 * MB];
    public static void main(String[] args) {
        GCTest01 a = new GCTest01();
        GCTest01 b = new GCTest01();
        a.instance = b;
        b.instance = a;

        a=null;
        b=null;
        System.gc();

    }
}

在这里插入图片描述
这里好像是用的G1收集器,最后用了Full gc,一个young region是1024k,0survivors,最后没有存活的对象:(这里还不太明白,欢迎大佬指正)

  • 可达性分析
    在这里插入图片描述
    通过GC Roots集合中根对象区寻找对象,m3就找不到,就回收
    GC Roots包含那些就是重点了:
    1、虚拟机栈(栈帧中的局部变量表)中引用的对象(就是存储方法中的基本数据类型和引用对象)
    2、方法区的类属性引用对象
    3、方法区中常量引用的对象
    4、本地方法栈中应用的对象

垃圾回收算法

分代收集理论
新生代:大批对象死去
老年代:回收存活的少量对象就放里面了
垃圾收集算法
对同一个区域中可回收的打上标记进行分类在回收
标记-复制:原来的内存对半分,然后存活的对象复制到另一块区域,一次清理一块区域
在这里插入图片描述
直接每次把上面的区域全清了
标志-整理算法:在上面的基础上,不分区域,让存活的对象向一端移动,清理掉存活对象边界以外的
(老年代存活对象多就移动的代价就大如果能操作失活的对象就小,个人玩笑

## 垃圾收集器

介绍下cms和g1
CMS:基于标记-清除算法

  • 初始标记
  • 并发标记
  • 重新标记
  • 并发清除
    不想写了
    大约就是先小标记-遍历整个对象图-修正线程运行导致的对象标记变化-清除
    并发和用户线程一起,你在做事,他在监督,不过你是主导(修正阶段就体现)
    G1:基于Region的堆内存布局
    把真个堆内存划分成了一堆小的region
    抄下别人的图
    https://blog.csdn.net/weixin_43934607/article/details/109287602
    这个讲的很清楚
    Eden:新创建的对象放里面(一系列region的集合)
    survivor:回收过后的存活对象放里面({regions})
    然后有点类似于机器学习中的集成学习
    计算回收
    收益函数:region回收后内存能大多少以及回收时间
    就维护一个region优先级列表:先收集那块区域

差不多了,写作不易,给自己点歌赞

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java垃圾回收机制Java语言的一项重要特性,它可以自动管理内存,减轻了程序员手动释放内存的负担。Java垃圾回收机制主要通过垃圾收集器(Garbage Collector)来实现。 在Java中,当一个对象不再被引用时,就可以被判定为垃圾。垃圾收集器会定期扫描内存,找出不再被引用的对象,并将其回收释放内存空间。这样,程序员就不需要手动释放对象所占用的内存,大大简化了内存管理的工作。 Java垃圾回收机制基于以下两个核心概念: 1. 引用计数法:每个对象都有一个引用计数器,当有新的引用指向该对象时,计数器加1;当引用失效时,计数器减1。当计数器为0时,表示该对象不再被引用,可以被回收。但是,引用计数法无法解决循环引用的问题,即两个或多个对象相互引用,但与程序的根节点没有直接引用关系,导致无法被回收。 2. 可达性分析算法:Java垃圾回收机制采用可达性分析算法来判断对象是否可被回收。该算法从程序的根节点(如静态变量、方法参数等)出发,通过引用链追踪对象的引用关系,如果一个对象不可达(即无法通过引用链与根节点相连),则被判定为垃圾,可以被回收。 Java垃圾回收机制具有以下优点: 1. 简化了内存管理,减少了内存泄漏和野指针等问题的发生。 2. 提高了程序的可靠性和稳定性,减少了因为内存管理错误导致的程序崩溃。 3. 提高了开发效率,程序员不需要手动释放内存,可以更专注于业务逻辑的实现。 然而,垃圾回收机制也存在一些缺点: 1. 垃圾回收过程会占用一定的系统资源,可能会导致程序的运行速度变慢。 2. 垃圾回收的时间是不确定的,可能会导致程序在某些时刻出现短暂的停顿。 相关问题: 1. Java垃圾回收机制是如何工作的? 2. 什么是引用计数法?它有什么缺点? 3. 什么是可达性分析算法?它如何判断对象是否可被回收? 4. 垃圾回收机制有哪些优点和缺点?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值