jvm知识点与面试题

jvm

1. 定义:Java虚拟机(Java virtual machine),一种能够运行Java字节码的虚拟机。

1.1. Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。

2. jvm基本结构:

2.1. 1 类加载子系统(ClassLoader)

2.1.1. 用来装载.class文件

2.2. 2 运行时数据区(内存结构)

2.2.1. 方法区、堆、java栈、PC寄存器、本地方法栈

2.3. 3 执行引擎:执行字节码,或者执行本地方法

3. 2 JVM运行时数据区

3.1. 第一块:PC寄存器

3.2. 第二块:JVM栈

3.3. 第三块:堆(Heap)

3.4. 第四块:方法区域(Method Area)

3.5. 第五块:运行时常量池(Runtime Constant Pool)

4. 3 类加载器的流程

4.6. 类加载器的加载顺序

4.7. 双亲委派机制

5. 相关面试题

5.1. 1、JRE/JDK/JVM是什么关系

5.2. 2 双亲委派机制是什么?有什么作用?

5.3. 3 Java中垃圾收集的方法有哪些?

5.4. 4 如何判断一个对象是否存活?(或者GC对象的判定方法)

程序计数器:

  1. 定义:Java虚拟机(Java virtual machine),一种能够运行Java字节码的虚拟机。
    1. Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。

  

  1. jvm基本结构:
    1. 1 类加载子系统(ClassLoader)
      1. 用来装载.class文件
    2. 2 运行时数据区(内存结构)
      1. 方法区、堆、java栈、PC寄存器、本地方法栈
    3. 3 执行引擎:执行字节码,或者执行本地方法
  2. 2 JVM运行时数据区
    1. 第一块:PC寄存器
      1. PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。
    2. 第二块:JVM栈

      1. JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址。
    3. 第三块:堆(Heap)
      1. 它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。
    4. 第四块:方法区域(Method Area)
      1. 1)在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代。

        (2)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
    5. 第五块:运行时常量池(Runtime Constant Pool)
      1. 存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。
    6. 第六块:本地方法堆栈(Native Method Stacks)
      1. JVM采用本地方法堆栈来支持native(本地)方法的执行,此区域用于存储每个native方法调用的状态。
  3. 3 类加载器的流程
    1. 从类被加载到虚拟机内存中开始,到释放内存总共有 7 个步骤:加载,验证,准备,解析,初始化,使用,卸载。其中验证,准备,解析三个部分统称为连接
    2. 1 加载
      1. 将 class 文件加载到内存

      1. 将静态数据结构转化成方法区中运行时的数据结构

      1. 在堆中生成一个代表这个类的 java.lang.Class 对象作为数据访问的入口

    1. 2 链接
      1. 验证:确保加载的类符合 JVM 规范和安全,保证被校验类的方法在运行时不会做出危害虚拟机的事件,其实就是一个安全检查

      1. 准备:为 static 变量在方法区中分配内存空间,设置变量的初始值,例如 static int a = 3 (注意:准备阶段只设置类中的静态变量(方法区中),不包括实例变量(堆内存中),实例变量是对象初始化时赋值的)

      1. 解析:虚拟机将常量池内的符号引用替换为直接引用的过程(符号引用比如我现在 import java.util.ArrayList 这就算符号引用,直接引用就是指针或者对象地址,注意引用对象一定是在内存进行)

    1. 3 初始化

    1. 4 卸载
      1. GC 将无用对象从内存中卸载
    2. 类加载器的加载顺序

    1.  双亲委派机制
      1. 当一个类收到了加载请求时,它是不会先自己去尝试加载的,而是委派给父类去完成,比如我现在要 new 一个 Person,这个 Person 是我们自定义的类,如果我们要加载它,就会先委派 App ClassLoader ,只有当父类加载器都反馈自己无法完成这个请求(也就是父类加载器都没有找到加载所需的 Class)时,子类加载器才会自行尝试加载。
      2. 这样做的好处是,加载位于 rt.jar 包中的类时不管是哪个加载器加载,最终都会委托到 BootStrap ClassLoader 进行加载,这样保证了使用不同的类加载器得到的都是同一个结果。
  1. 相关面试题
    1. 1、JRE/JDK/JVM是什么关系
      1. JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台。所有的Java 程序都要在JRE下才能运行。普通用户只需要运行已开发好的java程序,安装JRE即可。
      2. JDK(Java Development Kit)是程序开发者用来来编译、调试java程序用的开发工具包。JDK的工具也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是 安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。
      3. JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分。它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统无关,实现跨平台。
    2. 2 双亲委派机制是什么?有什么作用?
      1. 1 是什么:双亲委派机制是当类加载器需要加载某一个.class字节码文件时,则首先会把这个任务委托给他的上级类加载器,递归这个操作,如果上级没有加载该.class文件,自己才会去加载这个.class。
      2. 2 有什么作用:

①防止加载同一个.class:通过委托去询问上级是否已经加载过该.class,如果加载过了,则不需要重新加载。保证了数据安全。

②保证核心.class不被篡改:通过委托的方式,保证核心.class不被篡改,即使被篡改也不会被加载,即使被加载也不会是同一个class对象,因为不同的加载器加载同一个.class也不是同一个Class对象。这样则保证了Class的执行安全。

    1. 3 Java中垃圾收集的方法有哪些?
      1. 采用分区分代回收思想:
      2. 1 复制算法

年轻代中使用的是Minor GC,这种GC算法采用的是复制算法(Copying)

a) 效率高,缺点:需要内存容量大,比较耗内存

b) 使用在占空间比较小、刷新次数多的新生区

      1. 2 标记-清除

老年代一般是由标记清除或者是标记清除与标记整理的混合实现

a) 效率比较低,会差生碎片。

      1. 3 标记-整理

老年代一般是由标记清除或者是标记清除与标记整理的混合实现

a) 效率低速度慢,需要移动对象,但不会产生碎片。

    1. 4 如何判断一个对象是否存活?(或者GC对象的判定方法)
      1. (1)引用计数法

给对象添加一个引用计数器,每次引用这个对象时计数器加一,引用失效时减一,计数器等于 0 时就是不会再次使用的。不过这个方法有一种情况就是出现对象的循环引用时 GC 没法回收。

      1. (2)可达性算法(引用链法) 

这是一种类似于二叉树的实现,将一系列的 GC ROOTS 作为起始的存活对象集,从这个节点往下搜索,搜索所走过的路径成为引用链,把能被该集合引用到的对象加入到集合中。搜索当一个对象到 GC Roots 没有使用任何引用链时,则说明该对象是不可用的。主流的商用程序语言,例如 Java,C#等都是靠这招去判定对象是否存活的。

程序计数器:

内存空间小,字节码解释器工作时通过改变这个计数值可以选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理和线程恢复等功能都需要依赖这个计数器完成。

posted @   taotooler  阅读(11)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示