【Java】有关JVM常见的一些问题

目录

JVM运行流程

JVM内存区域划分

线程私有

Java虚拟机栈

本地方法栈

程序计数器

线程共享

元数据区(方法区)

JVM类加载

类加载过程

双亲委派模型

垃圾回收机制

找到垃圾

计数算法

可达性分析算法

清除垃圾

标记清除算法

复制算法

标记整理算法

分代算法


JVM运行流程

【Java】有关JVM常见的一些问题_第1张图片


JVM内存区域划分

【Java】有关JVM常见的一些问题_第2张图片

线程私有

Java虚拟机栈

作用:描述的Java方法执行的内存模型。

内存模型:每个Java方法执行的时候都会创建一个函数的栈帧,包括:局部变量表,操作帧,动态链接,方法返回地址。

        局部变量表: 存储基本数据类型,对象引用。

        操作帧:每个方法会生成一个先进后出的操作栈。

        动态链接:执行运行时常量池的引用。

        方法返回地址:PC寄存器的地址。

生命周期:和线程的声明周期一样。

【Java】有关JVM常见的一些问题_第3张图片

本地方法栈

类似于Java虚拟机栈,但它是给本地方法使用的。

程序计数器

作用:用来记录当前线程执行的行号。

如果当前线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;
如果正在执行的是一个本地 方法,这个计数器值为空。

以上三个部分的数据区域都是每个线程私有的,每个线程创建出这样的空间来。 而接下来的堆和元数据区则是线程之间共享的区域。

线程共享

程序中所有创建的对象都在堆中。

堆中具体还会划分出几块不同区域,在垃圾回收部分详解。

元数据区(方法区)

存储被JVM加载的类信息、常量、静态变量。

在JDK1.8中,字符串常量池移到了堆中,之前是在元数据区。

总结一下:局部变量在栈,普通成员变量在堆,静态成员在元数据区。 


JVM类加载

类加载是非常复杂的过程,这里只是简单介绍一下。

类加载过程

【Java】有关JVM常见的一些问题_第4张图片 

加载:把字节码文件找到(.class),读取文件内容。(具体由三个类加载器工作完成,使用                 双亲委派模型)

验证:根据JVM虚拟机规范,检查字节码文件是否符合要求

准备:给类对象分配内存空间(此时内存初始化状态全为0)

解析:针对字符串常量进行初始化,把常量池中的符号引用转为直接引用的过程。

        符号引用:记录的不是真正的地址,而是相较于真正地址的偏移量。

        直接引用:解析后,把字符串常量放到真正的内存中的地址

初始化:执行类的构造器,把对象初始化,加载父类,执行静态代码块等。

双亲委派模型

该模型需要三个类加载器,分别是

BootstrapClassLoader:负责加载标准库中的类

ExtensionClassLoader:负责加载JVM扩展库

ApplicationClassLoader:负责加载用户提供的第三方库/用户项目代码中的类

其中ApplicationClassLoader有一个属性指向ExtensionClassLoader,ExtensionClassLoaderr有一个属性指向BootstrapClassLoader

该模型的执行顺序:

【Java】有关JVM常见的一些问题_第5张图片 


垃圾回收机制

垃圾:不再使用的内存,以对象为单位。

找到垃圾

计数算法

该算法是Python、PHP使用的。

它给每个对象都分配了一个计数器(整数)

当刚创建出该对象时,计数器为1,此后如果有其他引用指向该对象,计数器++。

销毁一个引用计数器--。

当计数器为 0 时,该对象就是垃圾了。

优点:简单有效

缺点:1. 内存浪费的较多

           2. 存在循环引用的问题,此时需要引入其他机制来解决该问题。

可达性分析算法

该算法是Java使用的。

Java中的对象都是通过引用来指向并访问的,引用中的成员又指向了其他对象。(形成树状结构)

JVM保存了所有对象。

每隔一段时间进行一下扫描,JVM从根节点(GCroots)出发,把可以访问得到的对象做个标记,不能访问到的全部当成垃圾回收了。

找到垃圾后就可以清除垃圾了。


清除垃圾

标记清除算法

【Java】有关JVM常见的一些问题_第6张图片

把垃圾标记出来之后,直接清除掉。

这样会产生大量的空间内存碎片。空间虽然还有,但是能够正常使用的就很少了。

复制算法

【Java】有关JVM常见的一些问题_第7张图片 

把内存空间化为两部分:把非垃圾的部分复制到一边,然后直接清楚掉另一边的全部空间。

空间利用率还是较低,并且当有效对象较多时,复制成本比较大

标记整理算法

【Java】有关JVM常见的一些问题_第8张图片 

刚开始和标记清除算法一样,但是它后面把有效对象都移动的一起。

提高了空间利用率,但是复制成本还是比较大。

分代算法

分代算法是整合了上述算法,让它们针对不同的对象适用不同的算法。

【Java】有关JVM常见的一些问题_第9张图片 


有什么错误评论区指出。希望可以帮到你。 

你可能感兴趣的:(jvm,java,算法)