深入了解JVM

虚拟机
在这里插入图片描述
在这里插入图片描述

java程序开发执行流程:
编译
Java文件 —javac编译— 》 class字节码-----java运行—》类加载 ---------》运行

java:编译性+解释性+静态语言

java:编译性+解释性+静态语言
动态语言支持
在这里插入图片描述

反射,
字节码技术:通过修改/获取字节码内容,达到代码中增强的目的
在这里插入图片描述

运行在JVM上的语言:kotlin,scala,groovy
独有的编译器和独有的JVM------
我们学习的java是运行在HotSpot虚拟机
1.一次编译,随处运行(跨平台)
2.JVM自动管理内存,不用手动管理(垃圾回收)
3.开发,执行流程中,存在编译+解释,运行时除了解释,还存在即时编译
4.java是静态语言,也提供了动态语言支持,—》动态代理
5.JVM有很多类型,我们使用HotSpot,实现了java虚拟机规范的JVM,基于自己独有的编译,还可以编译自己独有的语言,运行在自己独有的JVM上, 如。。。
6.对jmm,类加载,gc的掌握(垃圾回收)

JMM
在这里插入图片描述

java虚拟机栈:线程私有的,先进后出,
在这里插入图片描述

局部变量表:存储基本数据类型,对象引用,-11
在这里插入图片描述

JVM
1.区域划分
1线程私有:程序计数器,虚拟机栈,本地方法栈
2线程共享:方法区,堆
2.区域作用/保存的内容:
程序计数器:指定行号,程序上下文切换会使用
虚拟机栈:线程调用方法时,每个方法每次调用都生成一个栈帧
本地方法栈:线程调用native本地方法

堆:对象
3.结合代码能说明每个对象/变量/常量所处的区域
在这里插入图片描述

补充:StackOverFlowError异常,方法栈帧达到启动后规定的值

方法调用太多

注意:方法进入时生成我们的方法栈帧,入栈,方法返回,出栈

类加载
1.回顾父子类执行顺序
(1)父类的静态变量+静态代码块(书写顺序)
(2)子类的静态变量+静态代码块
(3)父类的实例代码块(书写顺序)
(4)父类的成员变量+构造方法
(5)子类的实例代码块
(6)子类的成员变量+构造方法

2.概述

从任何地方读取都可以,也可以在运行时动态的生成,不一定从Class文件加载
jsp本质上是一个Servlet
3.类的生命周期
前五步为类加载的过程
1.加载:
(2)中涉及到方法区所处的一个区域,JDK1.7再java内存,1.8是本地内存(名称改为原空间,原数据区)
java文件----》class文件类加载的第一个“加载”阶段

static final修饰的常量,class常量池即存在字面量及符号引用,

符号引用----》加载以后会转换为直接引用

java内存划分
jdk1.7
在这里插入图片描述

jdk1.8
在这里插入图片描述

2.验证:
在这里插入图片描述

规范验证,安全验证
3.准备阶段
在这里插入图片描述

解析:
在这里插入图片描述

初始化:
在这里插入图片描述
在这里插入图片描述

执行结果i=1
补充:对象的构造方法编译为字节码,也是类似收集的过程
收集成员变量+实例代码块+构造方法

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

类加载只会初始化一次,在虚拟机内部保证线程安全,

在这里插入图片描述

在这里插入图片描述

类加载器机制:双亲委派机制
在这里插入图片描述

先是查找,在进行加载:
1.从下往上查找,
2,从上往下加载
双亲委派模型/机制作用/好处:
好处:双亲委派模型 对于保证java程序的稳定性运作极为重要
缺陷/劣势:无法满足灵活的类加载方式
解决方案:自己重写loadClass破坏双亲委派模型
示例:SPI机制,
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:
1.讲类加载的五个阶段,可以概述说明每个阶段的作用,()
2.类加载器:从上到下说明四种类加载器
3.类加载机制:双亲委派机制/模型,大概介绍什么是?
好处?-----安全,不允许加载java.开头的类
缺陷?–不够灵活,

垃圾回收:Java进程再启动后创建垃圾回收线程,来对内存回收
垃圾回收的时机:System.gc()— ,显示的调用,建议jvm进行垃圾回收,一定情况下会触发FGC,生产上不建议用
JVM垃圾回收机制决定----创建对象时需要分配内存空间,空间不足,触发GC.。

垃圾回收的策略—如何判断对象已死?
1.引用计数算法
很难解决对象之间相互循环引用的问题
2.可达性分析算法
在这里插入图片描述
在这里插入图片描述
o0置为null,对象还在堆里,o0是不可达的,
即时编译器编译热点代码,

在这里插入图片描述

笼统放入理解 创建对象内存与vs gc
创建对象:再某个内存区域分配空间 ------空间是否足够,够的话,创建对象,不够的话–gc,gc完之后还不够则oom(内存溢出)
在这里插入图片描述
在这里插入图片描述

内存泄漏和内存溢出的区别:
内存泄漏:在进程运行时,不停放东西进去,不用的东西没有去掉,单块区域内存空间够不够,内存空间足够大,就不会发生溢出。
内存溢出:整个进程崩溃,
要在总结。。。。
1.什么意思,分别有什么作用,有什么后果
2.说明两者之间的关系,内存泄漏理论上经过一定时间会发生oom,理论上内存足够不会发生oom,
补充:内存泄漏相对来说影响没有oom那么大,还可以通过临时解决方案,
2.12Java虚拟机栈(线程私有)

永久代:方法区/元空间
新生代 和老年代构成堆
老年代
新生代:存活区
分代收集(jvm中GC)的内存划分

大多数Java对象又朝生夕灭的特性解释:
方法调用产生在方法返回后,方法栈帧出栈—》局部变量就没了,----》局部变量引用的对象不可达
minor gc:次要的垃圾回收
major gc:主要的垃圾回收

垃圾回收算法
1.标记-清除算法
类似遍历文件夹的下的子文件,标记废弃文件,删除。
标记出所有需要回收的对象
在标记完成后统一回收标记的对象
不足:1.效率问题,2.空间问题–

内存的使用可以不连续
数组里边存的是对象,引用的对象可以在不同的地方
2.复制算法(Copying算法)
新生代算法

内存利用率50%—缺陷
先找到文件夹下的有用子文件,复制到另一个文件夹,把之前的文件夹复制删除。

3.标记-整理算法
老年代收集算法
标记存活—》移动—》清理边界外内存
回收后内存空间是连续的(没有内存碎片)

8.垃圾回收的过程
在这里插入图片描述

紫色不可达,绿色可达
第一次只有伊甸区需要回收,一次垃圾回收,复制算法的内存利用率90%
9.4动态对象年龄判定

9.5空间分配担保

新生代gc:
1.大部分对象朝生夕死,所以使用复制算法
2.大部分情况下,s1空间足够存放存货对象
3.特殊情况,s1不足存放—》晋升到老年代(担保人)
minor gc 90%的空间取存活对象,复制到10%空间

10.用户线程得暂停:Stop-The-World(STW)

用户线程和gc线程执行得关系:
某个时间段,可能是:1.并行–已触发gc,而且没有安全问题
2.用户线程暂停,gc线程运行----已触发gc,但是有安全问题
3.用户线程执行,gc线程暂停—没有触发gc

吞吐量:用户线程执行时间/(用户线程执行时间+用户线程暂停时间)
判断垃圾收集器得性能指标(CPU利用率)
用户体验:单次用户线程暂停时间(STW)尽量越短越好----
判断垃圾回收器得用户体验
垃圾收集器

Serial收集器(新生代收集器,串行GC)
特性:单线程,复制算法,Stop The World(STW)
新生代gc:stw (暂停用户线程)
老年代gc:部分stw
吞吐量优先:Parallel Scanvenge+Parallel Old
用户体验优先:ParNew+CMS
CMS
在这里插入图片描述
在这里插入图片描述

缺陷:
1.内存碎片
2.浮动垃圾问题:
第四个阶段,用户线程产生得对象,如果进入老年代,而老年代空间不足,会出现”Concurrent Mode failure“,——》再次触发老年代gc,(使用Serial Old收集器)

G1 -用户体验优先
1.把heap划分为很多很多得region块,动态设置为Eden,Survivor,Tenured(老年代)
2.算法:整体上看是标记整理算法,局部看是复制算法
jvm参数,、

1.分配allocation4内存空间 ----在Eden区)
2.在Eden区空间6M,空间总共8M,要分配4M给allocation是不够的,空间不足——minor gc
对象优先分配在伊甸区

可以计算出老年代占用空间
3.执行GC:allocation1,2,3都可达——复制到s1放不下:分配担保机制,放到老年代

4.GC完,空间足够:分配allocation4对象得空间,对象得初始化,赋值
/**

  • 对象优先分配在Eden区
  • -XX:+PrintGCDetails -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M
  • 堆:20m
  • 新生代:10m,Eden=8m,S0=1m,S1=1m
  • 老年代:10m
    */
    public class Test {
    private static final int _1MB = 1024 * 1024;

public static void testAllocation() {
byte[] allocation1, allocation2, allocation3, allocation4;
allocation1 = new byte[2 * _1MB];//Eden
allocation2 = new byte[2 * _1MB];//Eden
allocation3 = new byte[2 * _1MB];//Eden
// 出现Minor GC
allocation4 = new byte[4 * _1MB];
}

public static void main(String[] args) throws Exception {
testAllocation();
}
}

/**

  • 大对象进入老年代
  • -XX:+PrintGCDetails -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:PretenureSizeThreshold=3145728
    */
    public class Test2 {
    private static final int _1MB = 1024 * 1024;

public static void testAllocation() {
byte[] allocation;
allocation = new byte[4 * _1MB];
}

public static void main(String[] args) throws Exception {
testAllocation();
}
}

java 程序得参数
补充一个:发生oom时,可以指定

jps。jmap、jstack重点一些
常用JVM监控工具(选学)
先通过jps找进程得pid
jmap堆转储信息
jstack:定位线程得问题,如死锁
ps查进程
jps查java

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值