JVM篇1:[-结构综述-]

栏目: Java · 发布时间: 6年前

内容简介:JDK:Java 语言的软件开发工具包(JRE: Java运行时环境(JVM: Java虚拟机(
java 虚拟机的介绍文章多如牛毛,写本文目的在于梳理一下,也方便以后翻来看看。  
另外网上文章的图都挺丑的,本文90%的图都出于在下亲笔,如图有错误,请指出,定当立即更正  
本文主要介绍一下Java虚拟机的抽象结构以及一些基础的概念
复制代码

一、几个概念简介

1.JDK、JRE、JVM

有了JRE就能运行java程序,如果只是运行软件,装个JRE就行了。
我们一般说java8,java10都是指的JDK,是java开发者使用的 工具 集,是一个大的概念,下面是java8的JDK组成
复制代码
JVM篇1:[-结构综述-]

2.JDK、JRE、JVM的关系

JDK:Java 语言的软件开发工具包( Java Development Kit )

JRE: Java运行时环境( Java Runtime Environment )

JVM: Java虚拟机( Java Virtual Machine )

JVM篇1:[-结构综述-]

3.历史上的java虚拟机类型

虚拟机即:模拟计算机功能,并提供统一操作接口,从而实现代码在不同平台的一致性。

从本质上来看,JVM是一个抽象接口,它有很多实现(如下),而这些实现也只是应用程序而已。

Java发展至今JVM也有过更新迭代,也有基于不同场景下使用的JVM。

JVM篇1:[-结构综述-]
Sun Classic VM 第一款商用Java 虚拟机,纯解释器方式执行java代码。(已退出历史舞台)
EXact VM 编译器解释器混合工作,很快被HotSpot VM取代(已退出历史舞台)
HotSpot VM 沿用至今
KVM 手机端----效率低(已退出历史舞台)
JRockit 专注服务端应用
J9 IBM公司
Microsoft JVM windows----平台专用(已退出历史舞台)
Taobao VM 淘宝根据HotSpot VM定制
Dalvik 安卓虚拟机,寄存器架构,执行.dex文件(.class-->.dex)
复制代码

4.Java虚拟机结构

JVM篇1:[-结构综述-]

二、Java虚拟机结构简述

1. .class 文件和 类加载器

1-1. .class 文件

如果对class感兴趣,可以详见 官方文档,对class文件介绍的非常细致 ,以后会写个专篇,这里不深入。

java第一天便知道javac命令能将.java生成.class文件,然后就上手IDE,基本也就与class文件无缘了

JVM篇1:[-结构综述-]
JVM篇1:[-结构综述-]

1-2.类加载器子系统

关于 类加载器子系统 这里展示也不深入,只要知道考它将java字节码文件载入JVM即可

详见: JVM篇2:[-加载器ClassLoader-]

JVM篇1:[-结构综述-]

2.运行时数据区

2-1. 程序计数器

当前线程私有,即每一个线程都有一个,通过改变它来选取下一条需要执行的字节码指令 
内存空间较小,JVM中唯一不会出现OutOfMemoryError情况
如果该线程正在执行一个本地方法,那么此时程序计数器的值是“undefined”
复制代码

2-2. Java虚拟机栈

调节参数:-Xss = 
---->[1.栈帧(StatckFrame)]-------------------------------------------
|--- 一个线程的每个方法在执行的同时,都会创建一个栈帧。  
|--- 栈帧中存储的有局部变量表、操作站、动态链接、方法出口等。  
|--- 当方法被调用时,栈帧入栈,当方法执行完成时,栈帧出栈。

---->[2.其他相关]-------------------------------------------
|--- 存取的速度快,仅次于寄存器
|--- 存储着方法的相关局部变量,包括各种基本数据类型,对象的引用,返回地址等。  
|--- 局部变量表的内存空间在编译器完成分配,运行期不能改变其大小

---->[3.异常相关]-------------------------------------------
栈溢出:    Java虚拟机会抛出StackOverflowError
内存溢出:  创建/动态扩展时没有足够的内存创建对应的Java虚拟机栈,抛出OutOfMemoryError异常
复制代码
JVM篇1:[-结构综述-]
JVM篇1:[-结构综述-]

2-3. Java虚拟机栈``本地方法栈

当前线程私有,本地方法栈支持Native方法调用
HotSpot VM将本地方法栈和Java虚拟机栈合二为一
异常情况:StackOverflowError和OutOfMemoryError
复制代码

关于线程私有和线程间共享,详见:Java内存模型(JMM--Java Memory Model)

2-4. 方法区

-XX:PermSize = 
-XX:MaxPermSize = 
---->[1.基本介绍]-------------------------------------------
当前线程共享区域:用于存储已经被虚拟机加载的[类信息](即加载类时需要加载的信息,
包括版本、field、方法、接口等信息)、final常量、静态变量、编译器即时编译的代码等。  

---->[2.运行时常量池]-------------------------------------------
|---用于存储编译期就生成的字面常量、符号引用、翻译出来的直接引用  
|---存储在运行时产生的常量(比如String类的intern方法,作用是String维护了一个常量池,如果调用的字符“abc”已经在常量池中,则返回池中的字符串地址,否则,新建一个常量加入池中,并返回地址)

[符号引用]:编码是用字符串表示某个变量、接口的位置,直接引用就是根据符号引用翻译出来的地址,将在类链接阶段完成翻译 

---->[3.异常相关]-------------------------------------------
异常情况:OutOfMemoryError异常。 
复制代码
JVM篇1:[-结构综述-]

方法区、永久带和元空间简介

JVM篇1:[-结构综述-]
方法区(Method Area):jvm规范里面的运行时数据区的一个组成部分(接口层面)
永久带(Perm):jdk7及之前的版本含有,是方法区的具体实现。(实现层面)
元空间(Metaspace):jdk8及之后的版本含有,是方法区的具体实现。(实现层面) # 元空间使用本地内存,不在JVM中

其实理解起来也不难:先定义和使用接口,再用具体实现完成工作。
复制代码

2-5. Java堆

JVM篇1:[-结构综述-]
Java 堆:存放对象
    |---新生代:存储新生的对象
        |--- Eden(E区):存放JVM中刚生成的Java对象
        |--- Survivor(S区)
            |--- FromSpace (S0)
            |--- ToSpace (S1)
    |---老年代:存储长期存活的对象
        |--- 年龄达标(新生代中GC下存活的次数),可通过 -XX:MaxTenuringThreshold 指定
        |--- 超大对象,直接进入老年代 。 

非堆:存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。
复制代码
-XX:NewSize=        新生代大小
-XX:SurvivorRatio=  E区与两个S区的比值 默认 8:2
-XX:NewRatio=       新生代和老年代的比值  
-XX:MaxTenuringThreshold 进入老年代年龄阀值

-Xms 初始堆大小 : 默认是物理内存的1/64
-Xmx 最大堆大小 : 默认是物理内存的1/4
-XX:PermSize= 非堆内存初始值: 默认是物理内存的1/64
-XX:MaxPermSize= 最大非堆内存: 默认是物理内存的1/4
堆大小:新生代 + 老年代 + 持久代
复制代码

三、堆与垃圾回收机制

Minor GC : 清理新生代
Full GC  : 清理整个堆空间
复制代码

1:MinorGC

一般新创建对象进入E区,当E区内存用完后,触发MinorGC。
存活的对象最终进入SurvivorFrom
复制代码
JVM篇1:[-结构综述-]

2.Survivor的两个区域 FromTo

1.当E区再度装满
2.触发MinorGC回收
3.存活的对象(包括From中)复制存放入To
4.To和From调换名称
复制代码
JVM篇1:[-结构综述-]

3.几个小问题:

[1].为什么要分新生代和老年代?
|--- 对象的生存状况不同,使用不同的回收算法,优化GC性能
|--- 在新生代对象可能被频繁创建或销毁(朝生夕死),老年代对象回收较少

[2].Survivor区存在的意义? 
提高对象进入老年代的门槛,减少FullGC 的次数(FullGC很耗时)

[3].S0和S1有什么作用?  
避免Survivor区空间的碎片化
复制代码

四、垃圾回收算法

垃圾对象的判定
    |---引用计数法
    |---可达性分析
回收算法
    |---标记清除
    |---复制
    |---标记整理
    |---分代收集
垃圾回收器:
    |---Serial
    |---Parnew
    |---CMS
    |---G1
复制代码

1.垃圾对象的判定

1-1.引用计数法

在对象中添加引用计数器,当该对象被引用时,引用计数器+1,引用失效时,计数器-1
对象循环引用会失效
复制代码

1-1.可达性分析

Java中GC Root包括 :

[1].虚拟机栈中的引用的对象。
[2].方法区中的类静态属性引用的对象。
[3].方法区中的常量引用的对象。
[4].本地方法栈(jni)即一般说的Native的引用对象。
复制代码
JVM篇1:[-结构综述-]

一个对象和GC Root之间没有链接,那么该对象可回收

比如 ObjC和ObjB 之间的连接断开,橙色区域的对象可回收

2.回收算法

2-1: 标记-清除(Mark-Sweep)

JVM篇1:[-结构综述-]
---->[方式]----------------------------------
[1].标记出所有需要存活的对象
[2].标记完成之后统一回收掉未被标记的对象。

---->[缺点]----------------------------------
[1].标记和清除效率都不高。
[2].会产生大量的不连续的内存碎片。
大量空间碎片的缺点:当程序需要为较大对象分配内存时,无法找到足够的连续内存而出发GC。
复制代码

2-2: 标记-整理(Mark-Compact)

JVM篇1:[-结构综述-]
---->[方式]----------------------------------
[1].标记出所有存活的对象
[2].让所有存活的对象都向一端移动,在移动过程中清理掉未标记的对象

---->[优劣]----------------------------------
优:不会产生大量不连续内存碎片问题
劣:要执行较多的复制操作,效率将会变低,不适合存活率高的情况
复制代码

2-3: 复制算法(Copy)

JVM篇1:[-结构综述-]
---->[方式]----------------------------------
[1].将可用内存按容量分成大小相等的两块,每次只使用其中一块。
[2].回收时,将内存中存活的对象复制到另一块内存,然后清理掉该内存空间

---->[优劣]----------------------------------
优:无空间碎片,实现简单,运行高效
劣:可使用的内存降为原来一半
复制代码

2-4:分代收集

这不是什么算法,而是根据不同的代来使用何时的算法

新生代:可回收对象较多,回收率大。
    |--- 复制算法,高效,无碎片,从E区到S区。
老年代:可回收对象少,回收率低。
    |--- 标记-整理算法,无碎片。
复制代码

3.垃圾回收器简介

---->[新生代回收器:minor GC]----------------------------
[1].Serial(串行GC)-复制
[2].ParNew(并行GC)-复制
[3].Parallel Scavenge(并行回收GC)-复制

---->[老年代回收器:full GC]----------------------------
[4].Serial Old(MSC)(串行GC)-标记-整理
[5].CMS(并发GC)-标记-清除
[6].Parallel Old(并行GC)--标记-整理

---->[G1独立完成]-------------------------------
[7].G1(JDK1.7+)
复制代码
JVM篇1:[-结构综述-]

好了,综述就到这里,具体详情可见接下来的各篇专题。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Design systems

Design systems

Not all design systems are equally effective. Some can generate coherent user experiences, others produce confusing patchwork designs. Some inspire teams to contribute to them, others are neglected. S......一起来看看 《Design systems》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具