jmmjvm流程+细节整理

本文详细梳理了JVM的运行流程,从.java文件的编译到类加载,再到内存区域的分配与GC机制。重点介绍了类加载的双亲委派模型,以及内存中的程序计数器、虚拟机栈、本地方法栈、Java堆和方法区的作用。此外,还探讨了对象创建的过程及GC的工作原理,包括标记-复制算法在新生代的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jvm运行流程

简述:
1、.java后缀的文件
2、静态编译器通过词法语法分析编译为class文件(字节码)。
3、class文件通过jvm加载到内存中,通过类加载器(双亲委派)加载。
4、在jvm内存中的表现就是对象放到堆中,类的信息、静态变量放到元数据区(java8,其他版本的类推,原理一样)
5、用户线程访问程序,线程的私有变量放到栈中,调用的本地方法(比如system.currentmills)产生的本地方法数据放入到本地方法栈,生成的对象放到堆中。
6、随着程序的运行,堆栈会进行gc。根据不同的情况进行gc。

以下针对上面的流程进行细化。【太细化可以写一本书出来,这里只是简单的细化】

1、没啥好说。
2、编译为class文件的细节。意义非凡,实现了跨平台,不是直接将代码编译为机器码,而是字节码。字节码文件时二进制流。其中每一个二进制代码都有其特殊的含义,有点像密码对照表,每一个二进制码都能从规定好的规则中找到对应的解释。
编译的步骤:加载,检查格式,准备(给静态变量分配内存空间),解析(初始化常量),初始化(给静态变量和静态代码块初始化)。
3、class加载的细节。
3.1、大的层面,所有文件的三种模式:JIT编译和解释混合执行(默认)。好处:解释执行速度快。编译执行是针对热点代码,直接编译为机器码,可以更加快速的运行(面向cpu),得益于JIT的动态编译技术。
3.2、小的层面,具体到每个文件的加载流程。

3.3 双亲委派的原理:让爸爸先来加载,加载不了的子类再来。
双亲委派的作用(父类和子类加载器是复合模式,不是继承):不同的类加载器加载的类不相同,即使是同一个文件,所以可以保证加载的基础类的统一;另外保证了安全性,加入用户重写了一个核心类,必须经过父类加载后才能进行加载,而父类发现这个类以及加载,所以不会再加载。
双亲委派特别说明:不是必须的加载模式。总有一些其他的场景是满足不了的。

4、加载的class在内存中的表现。
4.1 内存表现
程序计数器:没有oom,线程私有,这个和cpu的寄存器一个道理。线程执行和恢复都依赖它。保存了 程序的偏移量和行号指示器等。
虚拟机栈:有oom,记忆中的堆栈中的栈就是☞这里的局部变量,可以说记忆中的栈是虚拟机栈的子集。
本地方法栈:通过JNI调用,不受jvm控制,好处是复用非java代码。(大概的理解就是调用了非java语言编写的方法)
java堆:有oom, 需要的内存最大,线程共享,作用是来保存对象实例。需要gc回收。有新生代和老年代之分,这样分层可以做到对java对象内存做更加精细化的控制。
方法区:有oom, 作用类似于堆,保存静态变量,常量等。(java1.8已经被元空间代替
运行时常量池:这个理解需要设计到java语言编译的运行流程。 (java1.8已经被元空间代替

4.2 为什么有两个survivor区。
典型的空间换时间。关键词是内存碎片导致的空间和性能的损耗。
因为新生代会频繁的进行gc,所以碎片很严重,有两个surivvor区的话,每次保证有一个s区是空的,可以进行内存整理,如果只有一个的话,进行整理会耗费很多性能,空的情况直接放进去就行。

5、对象创建。

java对象底层的创建-内存布局-定位。
大概的理解:
1、创建 - cas算法分配内存。指针碰撞或者空闲列表。
2、布局:对象头header / 有效数据 / 对齐填充
3、访问使用:句柄和指针。句柄的话堆中有块句柄池用来保存对应关系。指针的话直接访问,一步到位。优点就是对象的句柄池中的地址是稳定的。指针的优点是更快。占用空间也更少。

6、gc详情。
有个前提需要知道:常规gc会导致应用不可用。
上面说了,新生代会频繁gc,这样碎片太多的话,会进行FGC(全盘gc,更加影响性能),所以为了避免这种情况,采用空间换时间。采用标记-复制算法。
原理:对所有的对象从root出发进行标记,将有标记的进行复制到另外一块空的地方(s0),并将剩下的删除,循环反复。
垃圾收集器十多种。
1.8:默认的垃圾收集器:parallel-scavegel. 又名吞吐量优先收集器。适合新手。jvm会自动调节。尽可能减少系统的停顿时间。新生代使用的是标记-复制算法。老年代采用的是标记-整理算法。是根据不同代数据不同的特性而采用改的不同算法。
1.9以上: G1。新的垃圾收集器。

对象进行回收的条件:
可达性算法。根据Gcroot是否可达。
什么是Gcroot:
1、虚拟机栈中的引用对象
2、静态属性引用的对象
3、静态常量引用的对象
4、本地方法栈中引用的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值