JVM统合笔记,方便快速了解JVM相关知识

JVM通过在不同操作系统上运行特定的JVM实现跨平台。它加载字节码,使用JIT编译器提高效率,并通过类加载子系统进行验证、准备和解析。内存区域包括方法区、堆、虚拟机栈等,其中垃圾回收机制确保无效对象被释放,防止内存溢出。文章还讨论了不同类型的垃圾收集算法和Tomcat中类加载器的使用。
摘要由CSDN通过智能技术生成

JVM为什么能跨平台,原理?

本质就是不同操作系统上运行的JVM是不一样的,这才是JVM跨平台本质。

jvm,字节码

jvm整体架构

正在上传…重新上传取消

类加载子系统将字节码从磁盘读取到内存中。

热点字节码指令只翻译一次(JIT编译器)

JIT编译器对于热点的字节码指令翻译成机械指令缓存起来提高效率。

JVM执行流程(简单)

首先是源文件编译成字节码文件,之后通过类加载子系统将磁盘中的字节码文件读取到内存中去,首先是读取到方法区中,我们的字节码文件需要用到解释器解释为机械指令,其中的热点字节码文件会被JIT编译器翻译成机械指令,之后其中的对象放入到堆中,jvm本地方法放到本地方法栈,java有关的创建的一些变量存放在java方法栈中,程序计数器存放将要执行下一条指令的地址。

类加载子系统

正在上传…重新上传取消

链接阶段

验证待加载class文件是否正确,比如验证文件格式,准备阶段是为static变量分配内存并赋零值,解析阶段是将符号引用解析为直接引用,符号引用就是方法名,直接引用是方法的地址。

类加载器分类

分为引导类加载器(BootStrapClassLoader)(JVM内部默认提供)与自定义类加载器(继承实现ClassLoader类)

自定义加载器指的就是我们自己写的类继承实现了ClassLoader类。而我们默认使用的是引导类加载器和EXTclassLoader(扩展类加载器),AppClassLoader(应用类加载器)之后包括我们使用Tomcat时tomcat会帮我提供一个WebAppClassLoader类加载器。

三个默认类加载器对应的加载目录分析(在Launcher下)

EXT:

APP:

引导类加载器加载(/jre/Lib)

双亲委派模型

正在上传…重新上传取消

主要是负责避免类的重复加载

防止核心API被篡改(获取到String.class.getClassLoader()方法返回的是null,这说明我们返回的是BootStrapClassLoader()加载的,而外面黑客所加载的是加载不到我们内部这个)

用的ClassLoader中的loaderClass 。

Tomcat中为什么要自定义类加载器?

正在上传…重新上传取消

虽然是我们自己写的类去继承加载自定义类加载器,但是其实使用的是它的一个实例对象。

JVM判断一个类是不是已经被加载的逻辑是:类名+对应的类加载器实例。

不同应用写了多个一样的,只用AppClassLoader只能加载一个。其他的就是不可以被加载了,名字相同。所以就是针对应用A,B各自独立的设置类加载器也就是WebAppClassLoader。这个两个一个用中的就是都被各自的类加载器所加载,不会冲突。这就是Tomcat自定义类加载器的核心原因,是为了实现类加载的隔离。

JVM整体结构(运行时数据区域由哪些部分组成他们的作用)

正在上传…重新上传取消

正在上传…重新上传取消

方法区中包含了常量池,方法信息和类信息。是线程公用的。java方法栈中是很多个栈帧(每个线程都有一个)还有堆,程序计数器是下一次指令地址,本地方法栈中存放jvm的方法。

程序计数器作用

正在上传…重新上传取消

OutOfMemoryError内存溢出错误

虚拟机栈(java栈,java方法栈)

正在上传…重新上传取消

StackOverFlowError:栈溢出错误。

每个线程创建时候都会创建一个虚拟机栈,栈会保存一个个的栈帧,每个栈帧都会对应一个方法。

1,虚拟机栈是线程私有的

2,一个方法开始执行栈帧入栈,方法执行完对应的栈帧就会出栈,所以虚拟机栈不需要进行垃圾回收。

3.虚拟机栈会存在OutOfMemoryError,和StackOverFlowError

4,县城太多,会可能出现内存溢出,线程创建时没有足够的内存区创建虚拟机栈

5,方法调用层次太多,就可能会出现栈溢出

6,可以通过-Xss来设置虚拟机栈的大小。

栈帧(局部变量表和操作数栈有什么作用,如何工作的?)

正在上传…重新上传取消

包含局部变量表,操作数栈,方法返回地址,动态链接以及附加消息。

局部变量表中就是我们创建的局部变量,操作数栈也是操作栈,是用来执行字节码指令过程中用来计算的。

局部变量表的作用就是对数据进行一个实时的记录。

操作数栈就是字节码执行过程的计算。

本地方法栈(native method)

正在上传…重新上传取消

堆区以及其中区域作用

正在上传…重新上传取消

堆是JVM中最重要的一块区域,JVM规范中规定所有的对象和数组都应该存放在堆中,在执行字节码指令时,会把创建的对象存入堆中,在执行字节码指令时,会把创建的对象存入堆中,对象的引用地址存入虚拟机栈中的栈帧中,不过当方法执行完之后,刚刚创建的对象不会被马上回收,而是要等到JVM后台执行GC后(垃圾回收)对象才会被回收。

堆初始化内存与最大内存:

正在上传…重新上传取消

老年代与新生代:

正在上传…重新上传取消

新生代:

正在上传…重新上传取消

新生代分为Eden区与s0,s1区

Eden:伊甸园区,新对象都会先放到Eden区(除非对象大小都超过了Eden区,那么就只能直接进入老年代)

s0,s1:Survivor0,1区,也叫from区域,to区,用来存放MinorGC(YGC)后存在的对象。

默认比例为8:1:1,也就是Eden区占新生代大小的十分之八,可以通过-XX:SurvivorRatio来调整。

java对象在各个区流畅过程

垃圾回收流程:

首先是对象放在Eden区:之后存满了之后进行垃圾回收(YGC)之后放入到s0区,之后满了在进行回收放入到s1区域,往复,之后超过十五次放入到老年代中,如果比较大对象那么先放入到Eden中之后s0,1放不下那么放入到老年代,如果超大对象(文件)直接放入到老年代。

垃圾回收:

Young GC/Minor GC:负责对新生代进行垃圾回收。

Old GC/Major GC:负责对老年代继续宁垃圾回收,目前只有CMS垃圾收集器会单独对老年代进行垃圾收集,其他垃圾收集器基本都是整对回收的时候对老年代进行垃圾收集。

Full GC:针对回收,也会堆方法区进行垃圾收集

垃圾回收之引用计数法思路:

为什么要进行垃圾回收?

垃圾是指再JVM中没有任何引用指向它的对象,如果不清理这些垃圾对象,那么它们就会一直占用着内存,而不能给吧其他对象使用,最终垃圾对象越来越多,就会出现OOM。

垃圾标记阶段:

也就是找到JVM(主要是堆中)有哪些垃圾对象,两种方式:

引用计数法:正在上传…重新上传取消

每个对象都保存一个引用计数器属性,用户记录对象被引用次数。

实现简单,计数器为0是垃圾

需要额外空间来储存引用计数,

需要额外时间来维护引用计数,

无法处理循环引用问题。

可达性分析法:

正在上传…重新上传取消

以GC Root作为起始点,一层一层找到所引用对象,找到就是存活,没找到不可达就是垃圾对象。

正在上传…重新上传取消

GC Roots是一组引用,包含:

虚拟机栈中,本地方法栈正在执行方法中的方法参数,局部变量所对应的对象引用。

方法去中保存的类信息中静态属性,常量属性所对应的对象引用。

标记-清除算法

正在上传…重新上传取消

基础和常用的垃圾回收算法,针对某块内存空间,比如新生代,老年代,如果内存不足就会进行STW,暂停用户线程执行,然后执行算法进行垃圾回收:

1,标记阶段:GC Roots开始遍历,找到可达对象,并且再对象头中记录

2,清除阶段:对堆内存空间进行线性遍历,如果发现对象头中没有记录是可达对象,进行回收。

缺点是:效率不高,内存碎片

优点:实现简单

复制算法(空间换时间)

正在上传…重新上传取消

将内存空间分为两块,每次只使用一块,在进行垃圾回收时,将可达对象复制到另外没有被使用的内存块中,然后再清除当前模块中所有对象,后续按照流程,交换进行。

正在上传…重新上传取消

优点:没有标记,清除阶段,通过GC Roots找到可达对象,直接复制,不需要修改对象头,效率高。不会出现内存碎片。

缺点:

需要更多的内存,始终有一半的内存空闲。

对象赋值后,对象存放的内存地址发生了便能话,需要额外的时间修改栈帧中的记录的引用地址。

用在(新生代)如果可达对象比较多,垃圾对象比较少,那么复制算法的效率就会比较低,所以,垃圾对象比较多情况下,复制算法比较合适。

标记整理算法

正在上传…重新上传取消

分为三个阶段

第一个阶段和标记清除算法一样,从GC Roots找到并且标记可达对象。

第二个阶段将所有存活对象移动到内存的一端

最后清理边界外所有空间。

缺点是效率比较低,还要修改栈帧的地址

对比总结

正在上传…重新上传取消

分代收集算法

正在上传…重新上传取消

老年代中对象存活时间比较长,不适合复制算法,适合标记清除和标记整理算法。

CMS垃圾收集器采用的就是标记清除算法

Serial Old垃圾收集器采用的就是标记整理算法

常见垃圾收集器

正在上传…重新上传取消

Serial GC串行,工作暂停,一个线程进行垃圾回收,复制算法。

Old老年代,标记清除算法

Parallel Gc并行,工作暂停,多个线程进行垃圾回收,新生代使用复制算法

Old老年代,标记整理算法

CMS垃圾回收器(低暂停)

正在上传…重新上传取消

正在上传…重新上传取消

正在上传…重新上传取消

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值