JVM基础

一、初识JVM

二、字节码文件详解

(一)、JVM的组成

(二)、字节码文件的组成

1、基本信息

 JDK8及以后,主版本号-44=JDK版本

2、常量池

3、方法

 

(三)、类的生命周期

1、概述

2、加载阶段

3、连接阶段

(1)、验证阶段

(2)、准备阶段

 注意特例:

(3)、解析阶段

4、初始化阶段

(1)、概述

(2)、练习一

 先初始化main方法所在的类,打印D,在打印A,创建对象时先执行搞糟代码块,打印C,执行构造方法打印B,打印CB

(3)、练习二

创建父类,子类不会初始化

创建子类,父类会初始化

 (4)、练习三

 

(四)、类加载器

1、JDK8及以前类加载器的分类

(1)、启动类加载器

(2)、扩展类加载器

(3)、应用程序类加载器的

2、双亲委派机制

 

3、打破双亲委派机制

(1)、自定义类加载器

loadClass双亲委派机制源码

Class loadClass{
    
    //双亲委派机制部分代码

    Class findClass{
        
        //根据路径获取字节码二进制文件

        Class defineClass{
            //对字节码二进制文件进行校验
            //将二进制文件加载到方法区和栈中

        }

    }


}

打破双亲委派机制:

自定义类加载器,重写loadClass()方法,删除双亲委派机制部分代码,直接加载二进制文件,然后调用defineClass()方法

如果自定义类加载器而不想破坏双亲委派机制,应该重写findClass()方法

(2)、线程上下文类加载器

SPI机制

 

 (3)、Osgi框架的类加载器

4、JDK9以后的类加载器

5、总结

 

三、JVM的内存取区域(运行时数据区)

(一)、程序计数器

 

(二)、栈

1、虚拟机栈

2、栈帧组成

(1)、局部变量表

(2)、操作数栈

 

(3)、帧数据

动态链接

方法出口

 异常表的引用

3、虚拟机栈内存溢出

(三)、堆(线程之间共享)

堆内存大小是有上限的,当对象一直向堆中放入对象达到上限之后,就会抛出 OutOfMemory
错误

(四)、方法区(共享)

 1、类的元信息

2、运行时常量池

3、字符串常量池

false

true

JDK6中

JDK8(7及以后)中

(五)、直接内存(共享)

(六)、总结

四、垃圾回收

(一)、方法区的回收

我们平时所写的代码都是由应用程序类加载器加载的,应用程序类加载器不会被回收所以我们写的类不会被回收

(二)、堆回收

1、引用计数法和可达性分析法

(1)、引用计数法

(2)、可达性分析法

哪些对象被称之为GC Root对象呢?
  •  线程Thread对象。
  • 系统类加载器加载的java.lang.Class对象。(一般关联着静态变量)
  • 监视器对象,用来保存同步锁synchronized关键字持有的对象。
  • 本地方法调用时使用的全局对象。

2、五种对象引用

(1)、强引用
可达性算法中描述的对象引用,一般指的是强引用,即是GCRoot对象对普通对象有引用关系,只要这层关系存在,普通对象就不会被回收
(2)、软引用

软引用对象设计

在每次放入hashmap中时,对队列进行遍历删除,hashmap根据软引用对象中的key删除相应的key和value

(3)、弱引用

用法和软引用相似

(4)、虚引用

(5)、终结器引用

3、垃圾回收算法

(1)、标记清除算法

(2)、复制算法

(3)、标记整理算法

(4)、分代GC

 minor GC用的是复制算法

 不一定是年龄到达15的时候才能进入老年代,如果年轻代已经满了,年轻代的对象会提前进入老年代,所以要先进行mirror GC,失败再进行Full GC

4、垃圾回收器

(1)、年轻代-Serial

Serial和SerialOld适用于CPU资源匮乏的情况下,都是单线程回收

(2)、老年代-SerialOld

Serial和SerialOld适用于CPU资源匮乏的情况下

(3)、年轻代-ParNew

多线程回收

(4)、老年代- CMS(Concurrent Mark Sweep)垃圾回收器

尽量减少STW时间

CMS执行步骤:
1.初始标记,用极短的时间标记出GC Roots能 直接 关联到的对象。
2.并发标记, 标记所有的对象,用户线程不需要暂停(但是如果并发标记线程占用的CPU资源非常多,也会影响用户线程的执行)。
3.重新标记,由于并发标记阶段有些对象会发生了变化,存在错标(本来是存活的,用户线程将其变得不存活)、漏标等情况(用户线程新创建出来的对象,还没来得及标记),需要重新标记。
4.并发清理,清理死亡的对象,用户线程不需要暂停。

(5)、年轻代-Parallel Scavenge

可以设置吞吐量和最大暂停时间

Parallel Scavenge是 JDK8默认 的年轻代垃圾回收器,多线程并行回收,关注的是 系统的吞吐量 。具备 自动调整堆内存大小 的特点
(6)、老年代-Parallel Old

 

(7)、G1

g1回收器总堆占有率到45%时会触发MixedGc,但年轻代需要到达60%才会触发youngGC,那岂不是每次到达45%时就直接触发MixedGC了吗? 

MixedGC有两种方式触发,一种是大对象直接入h,另一种走晋升。如果是走晋升,youngGC是MixedGC的前置,也就是g1应该优先younggc,毕竟mixedgc中的并发标记是依赖于younggc作初始标记的。younggc之后,正常系统绝大多数对象会被回收掉,满足晋升条件的对象晋升到老年代,这个时候才会去检测45%这个阈值,那很有可能由于youngc的对象释放,这个阈值已经不满足条件了。

(8)、总结 

  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值