笔记(五)- JVM

2022-06-10 20:17:19 浏览数 (1)

JVM的相关笔记。

1. 程序运行时数据区分为哪几个部分?

看一看 JVM运行时数据区

2.Java创建对象的过程

1、类加载检查:虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并检查这个符号引用代表的类是否已被加载过、解析过和初始化过。如果没有的话就必须执行相应的类加载过程。

2、分配内存:在类加载检查后,虚拟机会为新生对象分配内存。对象所需的内存大小加载完成后就可以知道,为对象分配内存空间的任务等于把一块确定大小的内存从Java堆中划分出来。分配的方式有 指正碰撞 和 空闲列表 两种,选择哪种分配方式由Java堆是都规整决定,Java堆是否规整由采用的垃圾收集器是否带有压缩整理功能决定。

  • 内存分配的方式: Java堆是否规整取决于GC收集器的算法是“标记-清除”还是 “标记-整理”(也叫做“标记-压缩”),复制算法的内存也是规整的。

(1)指针碰撞 适合场景:堆内存规整(即没有内存碎片) 原理:用过的内存全部整合到一边,没有用过的内存放到另一边,中间有一个分界值指针,只需要向着没用过的内存方向将该指针移动对象内存大小位置即可 GC收集器:Serial、ParNew

(2)空闲列表 适合场景:堆内存不规整的情况下 原理:虚拟机会维护一个列表,该列表会记录哪些内存是可用的,在分配内存的时候,找一块足够大的内存来划分给对象实例,最后更新列表记录 GC收集器:CMS

  • 内存分配的并发问题 在创建对象时,虚拟机保证线程安全的两种方式

(1)CAS 失败重试:CAS是乐观锁的一种实现方式,乐观锁就是每次不加锁而是假设没有冲突而去完成某项操作,如果有冲突失败就重试,直到成功为止。 虚拟机采用CAS加上失败重试的方法保证更新操作的原子性

(2)TLAB:为每个线程预先在Eden区分配一块内存,JVN在给线程的对象分配内存时,首先在ELAB分配,当对象大于ELAB的剩余内存或者ELAB的内存耗尽时,再采用CAS进行内存分配

3、初始化零值:内存分配完后,虚拟机需要将分配到的内存空间都设置为零值(不包括对象头),这一步操作保证了对象的实例在Java代码中可以不赋值就可以直接使用,程序能访问到这些字段的数据类型所对应的零值。

4、设置对象头:初始化零值后,虚拟机要对对象进行必要的设置。如一些对象属于哪个类的实例、怎么找到类的元数据信息、对象的哈希码等,这些信息存放在对象头中。

5、执行init方法:前4步完成之后,从虚拟机角度来看,一个新的对象已经产生,但从Java程序的角度,对象创建才刚开始,接着会执行init方法,把对象按照程序员的意愿进行初始化,这样才算真正完成对象的创建。

3.堆内存中对象的分配的基本策略

eden区、s0区、s1区都属于新生代,tentired区属于老年代。 大部分情况下,对象会首先在eden区分配,在新生代垃圾回收后,如果对象还存活,则会进入s0或s1区,并且对象的年龄还会加1(eden区->survivor区后对象的初始化年龄变为1),当它的年龄增加到一定程度时(默认15岁),就会晋升到老年代中。晋升到老年代的阈值,可以通过参数 -XX:MaxTenuringThreshold 进行设置。 大对象或者长期存活的对象会直接进入老年代

4.Minor GC和Full GC 有什么区别

大多数情况下,对象在eden区进行分配,当edne区没有足够的空间进行分配时,虚拟机会发起一次Minor GC

新生代GC(Minor GC):发生在新生代的垃圾回收动作,非常频繁,回收速度比较快 老年代GC(Major GC/Full GC):发生在老年代的垃圾回收动作,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC慢10倍以上

5.如何判断对象是否死亡

(1)引用计数法:给对象添加一个引用计数器,每当有一个地方引用到它,计数器就加1;当引用失效的时候,计数器就减去1;任何时候计数器为0的对象就是不可能再被使用的。

(2)可达性分析算法:通过一系列的“GC Root”的对象作为起点,从这些节点开始向下搜索,节点走过的路径为引用链,当一个对象的GC Root没有任何引用链相连的haunt,说明该对象不可用了。

6.简单介绍强引用、软引用、弱引用、虚引用

  • 强引用
  • 软引用

  • 弱引用

  • 虚引用

7.垃圾回收的算法

垃圾回收算法

8.HotSpot为什么要分为新生代和老年代

主要是为了提高GC的效率

参考:垃圾回收算法

9.常见的垃圾回收器

后面看完书再好好分析,先学习吧

10.类加载的过程

待学习

11.类加载器

JVM内置了三个重要的ClassLoader,除了 BootstrapClassLoader 其他类加载器均由Java实现并且全部继承java.lang.ClassLoader

1、BootstrapClassLoader(启动类加载器):最顶层的加载器,由C 实现,负责加载 %JAVA_HOME%/lib 目录下的jar包和类或者被 -Xbootclasspath 参数指定路径中所有类。

2、ExtensionClassLoader(扩展类加载器):负责加载目录 %JRE_HOME%/lib/ext 目录下的jar包,或者被 java.ext.dirs 系统变量所指定的路径下的jar包。

3、AppClassLoader(应用程序类加载器):面向用户的加载器,负责加载当前应用classpath下的所有jar包和类。

12.类的生命周期

加载、验证、准备、解析、初始化、使用、卸载

类的加载过程:加载、验证、准备、解析、初始化

12.双亲委派模型

待学习

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/笔记五-jvm

0 人点赞