【Java八股-第十期】JVM - Java基础
提纲:
🔥JVM
类加载器
作用
JVM默认类加载器
双亲委派模型
运行时数据区
执行引擎
本地接口
JMM
🎈面试八股真题
1、说说类加载与卸载
2、简述一下JVM的内存模型
3、说说堆和栈的区别
4、什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”?
5、Java内存结构
6、说说对象分配规则
7、说说Java对象创建过程
8、知道类的生命周期吗?
一、JVM
1. 类加载器
-
作用:
-
动态的将类的 class 加载至内存,防止一次性加载太多 class 导致程序崩溃,防止同一个类被重复加载
-
-
JVM 提供的默认类加载器:
-
1、BootstrapClassLoader:负责加载 JDK 的核心类库,最顶层的类加载器,由 c++ 实现,是 JVM 的一部分
-
2、ExtendClassLoader:负责加载 jre/lib/ext 目录下的类
-
3、AppClassLoader:负责加载 ClassPath 路径下的所有 jar 和 class
-
-
双亲委派模型
-
原理:Extend 和 App 类加载器在调用 loadClass 方法时,会先调用 findLoadedClass 方法检查是否已经被加载,加载时会先委派给上层类加载器的进行加载,即调用 parent.loadClass 和 findBootstrapClass 方法,若上层类加载器没找到,则由自己加载,通过双亲委派模型可以防止类重复加载对内存的消耗,并可以使类有一个优先级的层次关系,防止 Java 的核心类被覆盖
-
在调用 loadClass 方法加载类时,通过 Sychronized 锁保证线程安全
-
破坏双亲委派模型:通过自定义类加载器,继承 ClassLoader 并重写 loadClass 方法的规则
-
2.运行时数据区
-
堆内存
-
存储对象实例,包括新生代和老年代
-
对象头
-
Mark Word:包括对象的 hashcode,分代年龄 age,加锁情况
-
klass point:指向方法区中类的 klass 元信息
-
数组长度(数组特有)
-
-
对象的实例数据
-
-
方法区
-
类和方法的 klass 元信息
-
常量池
-
1.7 以前使用的 PermGen 永久代实现的方法区,1.8 之后使用的元空间实现的方法区,并将 static 静态变量和 StringTable 串池移动至堆内存,永久代的实现方式,堆内存与方法区在逻辑内存中是连续的空间,相当于是堆内存的一部分,因此可能会因为永久代空间不足引发 oom,元空间将方法区移动到了本地内存中,与堆空间的大小无关
-
-
栈内存
-
内部储存方法调用的栈帧
-
slot:栈帧中的局部变量表,存储基本类型和实例的引用
-
stack:操作栈
-
动态链接
-
方法返回地址
-
即将返回值压入返回地址的调用栈,没有返回值的话,cpu 根据计数器调用程序的下一条指令
-
-
-
-
程序计数器
-
本地方法栈
-
直接内存:ByteBuffer、CharBuffer 等 XXBuffer 类,可以通过 java 实现 NIO 的各种 XXChannel 类获得,也可以直接 new 创建,通过,NIO 解决了数据准备到内核缓冲区的阻塞,然而将数据从内核缓冲区拷贝至用户进程缓冲区仍要阻塞,ByteBuffer 通过内存映射的方式,使用户进程可以直接在内核的缓冲区中进行读写,不需要将数据拷贝至用户进程
-
# ByteBuffer 的垃圾回收,(Direct)ByteBuffer 通过 unsafe 来分配内存,并通过虚引用 Cleaner,将 ByteBuffer对象与一个 Deallocate接口绑定,在垃圾回收 ByteBuffer 时,就会将虚引用放入引用队列,并在垃圾回收结束后由 Reference Handler 线程调用 Deallocate 接口进行资源回收
3.执行引擎
-
及时编译器 JIT
-
解释器
-
垃圾回收器
4.本地接口
-
Native Interface本地接口
-
本地接口的作用是融合不同的变成怨言为Java所用,他的初衷是融合c/c++程序,Java诞生的时候时c/c++横行的时候,要想立足,必须调用c/c++程序,于是在内存中专门开辟出一块区域处理标记为native的代码,他的具体做法是Native Method Stack中登记native方法,在Execution Engine执行时加载native libraies。
目前该方法使用的越来越少了,除非是与硬件有关的应用,比如通过Java程序驱动打印机或者Java系统管理生产设备,在企业级应用中已经比较少见了。因为现在的异构领域间的通信很发达,比如可以使用Socket通信,也可以使用Web Service等等。
-
-
Native Method Stack
-
它的具体做法是在Native Method Stack中登记native方法,在Execution Engine执行时加载本地方法库
-
5.JMM
-
Java 内存模型,控制 Java 线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见,是一套内存使用规则
-
程序运行时,将内存分为线程共享的主存和线程本地私有的工作内存,主存与工作内存和 JVM 的内存划分没有关系,线程对变量的所有操作都是在工作内存中完成,然后再刷新到主存
-
JMM 定义了重排序的 happens-before 原则,sychronized 锁与 volatile 关键字都是其中的规定,来限制指令的重排序
二、面试八股真题🎈🎈🎈
1、说说类加载与卸载
-
加载过程
-
- 其中验证,准备,解析合称链接
-
-
加载通过类的完全限定名,查找此类字节码文件,利用字节码文件创建Class对象.
-
验证确保Class文件符合当前虚拟机的要求,不会危害到虚拟机自身安全.
-
准备进行内存分配,为static修饰的类变量分配内存,并设置初始值(0或null).不包含final修饰的静态变量,因为final变量在编译时分配.
-
将常量池中的符号引用替换为直接引用的过程.直接引用为直接指向目标的指针或者相对偏移量等.
-
-
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
【📫专栏目录在最底部📫】 - 本专栏适合于JAVA已经入门的学生或人士,有一定的编程基础。 - 本专栏特点: 本专刊囊括了JAVA、Spring、计算机网路、操作系统、计算机网络、MySQL、算法与数据结构、中间件等一系列知识点,总结出了高频面试考点(附有答案),事半功倍,为大家春秋招助力。 - 本专栏内容分为五章