兜兜零元 发表于 3 小时前

八股文-JVM

是什么?有什么用?谁发明的?什么时候发明的?

Java捏造机,用来运行Java步伐,有很多个版本的捏造机,比如HotSpot,最开始是SUN公司开辟职员,和Java一起发布,现在被Oracle收购了
盘算机不能直接运行吗?为啥要中间多一层捏造机?

盘算机可以执行机器代码,很多编程语言也是编译成机器码,j交给盘算机直接运行的,不外Java为了实现一次编写代码,可以跨平台执行,所以加了一层捏造机,同时捏造机也简化了我们的编码,比如自动内存管理、垃圾采取、编译优化(解释执行/即时编译)
特性

跨平台、安全、内存管理、性能优化(即时编译-JIT)、多线程支持
运⾏时数据区

方法区、堆、栈(Java方法栈、当地方法栈)、步伐计数器、
https://i-blog.csdnimg.cn/direct/ee71124b4f104e74982789c38b6adff5.png
类加载过程

类加载是指,把编译好的class文件加载到运行时数据区,必要颠末以下过程:
1、加载:加载是指查找字节省,并且据此创建类的过程。加载必要借助类加载器,在 Java 捏造机中,类加载器利用了双亲委派模子,即吸收到加载请求时,会先将请求转发给父类加载器。
2、链接:是指将创建成的类归并至 Java 捏造机中,使之能够执行的过程。链接还分验证、准备和解析三个阶段。其中,解析阶段为非必须的。分配内存、符号引用解析成为现实引用
3、初始化:类加载的最后一步是初始化,便是为标记为常量值的字段赋值,执行 < clinit > 方法,会加锁包管类的初始化仅会被执行一次,这个特性被用来实现单例的延伸初始化。
类加载器和双亲委派机制

启动类加载器(C++实现):启动类加载器负责加载最为底子、最为紧张的类,比如存放在 JRE 的 lib 目录下 jar 包中的类(以及由捏造机参数 -Xbootclasspath 指定的类)。
其他类加载器:都是 java.lang.ClassLoader 的子类,这些类加载器必要先由另一个类加载器,比如说启动类加载器,加载至 Java 捏造机中,方能执行类加载。双亲委派模子。每当一个类加载器吸收到加载请求时,它会先将请求转发给父类加载器。在父类加载器没有找到所请求的类的情况下,该类加载器才会实验去加载。
扩展类加载器(extension class loader)和应用类加载器(application class loader),均由 Java 核心类库提供。
扩展类加载器的父类加载器是启动类加载器。它负责加载相对次要、但又通用的类,比如存放在 JRE 的 lib/ext 目录下 jar 包中的类(以及由体系变量 java.ext.dirs 指定的类)。
应用类加载器的父类加载器则是扩展类加载器。它负责加载应用步伐路径下的类。(这里的应用步伐路径,便是指捏造机参数 -cp/-classpath、体系变量 java.class.path 或环境变量 CLASSPATH 所指定的路径。)默认情况下,应用步伐中包含的类便是由应用类加载器加载的。
Java 9有略微调整。
自界说的类加载器:本身实现的类加载器,可以满足一些自界说需求,比如对代码进行加解密
为啥要有双亲委派机制

包管一个类只被加载一次:由于父类加载了,子类就无需加载了,如许只会被加载一次
包管核心类库的安全性:防止子加载器去篡改核心类库的加载,比如写给自界说加载器把一些工具类给改了
解耦:类似与网络分层,各自做好本身的职责就行
解释执行/即时编译

解释执行:即逐条将字节码翻译成机器码并执行;
即时编译(JIT):即将一个方法中包含的所有字节码编译成机器码后再执行。
前者的上风在于无需等待编译,而后者的上风在于现实运行速率更快。HotSpot 默认采取混合模式,综合相识释执行和即时编译两者的长处。
理论上讲,即时编译后的 Java 步伐的执行效率,是大概凌驾 C++ 步伐的。这是由于与静态编译相比,即时编译拥有步伐的运行时信息,并且能够根据这个信息做出相应的优化。
https://i-blog.csdnimg.cn/direct/c1748e99e2be45d5a5e883cb8710fb6c.png
JRE、JDK、JVM关系?

JVM:Java捏造机,是一个可以执行 Java 字节码的捏造盘算机。
JRE:Java 运行时环境,是运行 Java 应用步伐所需的最小环境。包罗了 Java 捏造机(JVM)、核心类库和支持文件。
JDK: Java 开辟工具包,是用于开辟 Java 应用步伐的工具聚集,包罗了 Java 运行时环境(JRE)、Java 编译器(javac)、Java 捏造机(JVM)和各种工具(如 javadoc、javap 等)。
关系:
JDK 包含了 JRE 和开辟工具。
JRE 包含了 JVM 和运行 Java 步伐所需的类库。
总结:
如果你必要开辟 Java 步伐,必要安装 JDK。
如果你只必要运行 Java 步伐,安装 JRE 就充足了。
JVM 是 JRE 的核心部门,负责执行 Java 步伐。
垃圾采取

内存有限,对运⾏时数据区中的数据进⾏管理和采取。垃圾收集器分为串行、并行、并发。采取机制差别,吞吐量和相应时间差别。比如采取时间,各个阶段采取单线程还是多线程
Serial、Parallel、CMS、G1、ZGC。核⼼的算法有 3 个:标记-扫除、标记- 整理、复制
JVM调优

主要也是围绕吞吐量和相应时间,对应相应时间有要求的,那就尽量减少STW时间,反正就是通过一下工具看运行时,YGC和FGC次数,以及每次STW时间,通过不停调整和观测来设置一个合理的值
现实工作中一方面是调整JVM参数,另一方面是修改代码。
参数问题大概有以下一些情况:
1、堆内存设置太小,不满足步伐的正常运行,比如一个线程调用一个方法可以会占用1M,内存,并发数为1000,堆内存设置500M的话,一下就满了,这个时候大概会出现频仍垃圾采取大概OOM
2、堆内存新生代和老年代比例不合理,大部门都是临时对象的步伐,新生代可以调大。
3、还有一些参数可以指定STW最大时间,这时JVM会根据现实情况调整部门内存巨细
4、更换垃圾采取器,参考:https://blog.csdn.net/2301_79437276/article/details/140291840
一次GC流程

堆分为新生代和老年代,新生代分为E区和S区(S0、S1)。
新对象放入E区,大对象也大概直接放入老年代,E区满了会进行Young GC,存活下来的对象放入S区,S区内里存活下来的对象会进行一次负责,在S0和S1之间每复制一次,对象存活的分代年事+1,当达到15时放入老年代,老年代满了会进行Full GC
为啥是15呢?

由于分代年事存储在对象头内里,采取4bit存储,最大值只支持15
参考

https://www.cnblogs.com/tomakemyself/p/14147989.html

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 八股文-JVM