八股文-JVM

打印 上一主题 下一主题

主题 542|帖子 542|积分 1626

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

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

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

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

方法区、堆、栈(Java方法栈、当地方法栈)、步伐计数器、

类加载过程

类加载是指,把编译好的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++ 步伐的。这是由于与静态编译相比,即时编译拥有步伐的运行时信息,并且能够根据这个信息做出相应的优化。

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企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

兜兜零元

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表