JVM学习笔记(2)——MarkWord和GC入门


一、as if serial

不管如何重排序,单线程执行结果不会变

二、对象的创建过程

在这里插入图片描述

三、对象占用多少字节

对象的MarkWord一般占8字节,MarkWord的2位来表示锁的状态,分代年龄也在MarkWord里,表明这个对象被GC回收了多少次
+ UseCompressedClassPointers和+ UserCompressedOops,这2个参数是JVM默认开启的
UseCompressedClassPointers会把_class pointer从8字节压缩到4字节

UserCompressedOops会压缩对象的引用类型的成员变量。如图,String本来应该是8字节,由于这个参数,被压缩到了4字节
在这里插入图片描述

MarkWord

在这里插入图片描述
为什么GC年龄默认为15 ?
可以看到分代年龄占4位,而4位最多表示16种状态: 0~15。所以年龄最大是15,是这么来的

调用hasCode导致锁升级

在这里插入图片描述

四、GC

何为垃圾

单一个对象没被引用的时候,这个对象就成了垃圾

怎么发现垃圾

引用计数器

说白了就是一个对象被引用了,计算器+1,这个对象没被引用,计数器变为0,就回收。
引用计数器无法解决循环引用,A引用B,B引用C,C引用A,那么这3个对象永远无法被回收

GC Root(可达性分析算法)

JVM采用的是GC Root

此算法的核心思想:通过一系列称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索走过的路径称为“引用链”,当一个对象到 GC Roots 没有任何的引用链相连时(从 GC Roots 到这个对象不可达)时,证明此对象不可用。以下图为例:
在这里插入图片描述
在Java语言中,可作为GC Roots的对象包含以下几种:

  1. 虚拟机栈(栈帧中的本地变量表)中引用的对象。(可以理解为:引用栈帧中的本地变量表的所有对象)
  2. 方法区中静态属性引用的对象(可以理解为:引用方法区该静态属性的所有对象)
  3. 方法区中常量引用的对象(可以理解为:引用方法区中常量的所有对象)
  4. 本地方法栈中(Native方法)引用的对象(可以理解为:引用Native方法的所有对象)

GC算法

标记-清除算法

在这里插入图片描述
简单来说就是把没用的进行标记,然后清楚掉标记的
适用场景:存活对象比较多
缺点:需要进行2次扫描(一次标记,一次清除),容易产生内存碎片

复制算法

在这里插入图片描述
开辟一个新的空间,把存活的对象移动到新空间
适用场景:存活对象比较少的情况,因为涉及到了对象的移动,对象存活的少了,移动次数肯定少,效率自然高

标记-压缩

说白了就是把存活对象挤到一起,集中起来,然后剩下的垃圾对象直接清理
在这里插入图片描述

分代算法

分代算法其实跟垃圾回收器有关,ZGC之前所有的垃圾回收器都是分代算法。ZGC不在分年轻代和老年代

G1是逻辑分代,物理不分代

猜你喜欢

转载自blog.csdn.net/bookssea/article/details/121871367