- 1. JVM的位置?
- 2. JDK、JRE、JVM及JIT之间有什么不同?
- 3. java中会存在内存泄漏吗,请简单描述。
- 4. 32 位和 64 位的 JVM,int 类型变量的长度是多数?
- 5. 详细的介绍下程序计数器?(重点理解)
- 6. JNI是什么?
- 7. 双亲委派
- 8. PC寄存器
- 9. 方法区
- 10. 栈
- 11. 本地方法栈
- 12. 堆
- 13. 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。
- 14. 堆和栈的区别
- 15. 说一下 JVM由那些部分组成,运行流程是什么
- 16. 说一下JVM运行时数据区
- 17. 描述一下JVM加载class文件的原理机制?
- 18. Java程序运行机制详细说明
- 19. Java类加载器有哪些?
- 20. GC是什么?为什么要有GC?
- 21. 你知道哪些JVM性能调优?
- 22. GC常用算法
1. JVM的位置?
JVM 就是做用 在操作系统上的虚拟机。JVM虚拟机上才可以运行Java程序,在不同系统中安装不同版本的JVM,所以Java实现了跨平台
2. JDK、JRE、JVM及JIT之间有什么不同?
JVM: Java虚拟机, Java程序在JVM虚拟机上才可以运行,不同平台有不同版本的虚拟机,所以java实现了跨平台
JRE: Java的基础类库,JRE包括Java虚拟机和Java程序所需的核心类库。
JDK: Java的核心,JDK包括编译工具、和JRE基础类库
所以: JDK包含了JRE, JRE包含了JVM
JIT: 即使编译, 当代码执行的次数超过一定的阈值时,会将Java字节码转换为本地代码.
3. java中会存在内存泄漏吗,请简单描述。
会。自己实现堆载的数据结构时有可能会出现内存泄露,
4. 32 位和 64 位的 JVM,int 类型变量的长度是多数?
32 位和 64 位的 JVM 中,int 类型变量的长度是相同的,都是 32 位或者 4个字节。
![3`]KWT)9C[(8HRKAN8H(JW.png](https://cdn.nlark.com/yuque/0/2022/png/21644188/1642420936385-dfb0c02d-4b7f-4fe7-b982-69db2c4ddfa9.png#clientId=ucc60d6ca-26bc-4&crop=0&crop=0&crop=1&crop=1&from=drop&id=w5h6K&margin=%5Bobject%20Object%5D&name=3%60%5DKWT%299C%5B%288HRKAN8H%28JW.png&originHeight=494&originWidth=800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38328&status=done&style=none&taskId=u3f3b9897-b5ef-404a-9fb8-a34db5a4f96&title=)
![Z%O]_A4[ZZ1UY}TYKO]QOK.png
5. 详细的介绍下程序计数器?(重点理解)
程序计数器就是寄存器。指的是程序执行过程,保存当前线程所正在执行的字节码指令的地址(行号)。
每个线程工作时都有独立的计数器,只为执行Java方法服务,执行Native方法时,程序计数器为空.
6. JNI是什么?
JNI: java native interface 扩展java的使用,融合不同的编程语言为java所有.最终执行的时候, 通过JNI加载本地方法库中的方法。
7. 双亲委派
当一个类收到了类加载请求,它首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一层都如此,一直递归到顶层,只有当父类加载器无法完成这个请求时,子类才会尝试加载。
加载位于rt.jar包中的java.lang.Object类
8. PC寄存器
线程私有,保证线程的顺序
9. 方法区
方法区(Method area)是被所有线程共享,所有定义的方法的信息都保存在该区域,此区域属于共享区间;
如:static修饰的静态变量、final修饰的常量、class类信息(构造方法、接口定义)、运行时的常量池存在方法区中.
10. 栈
栈: 存储8种基本数据类型,对象引用,实例化的方法等. 它是先进后出、后进先出. main方法会先进入,最后出来. 线程结束,栈的生命周期就结束了.
栈+堆+方法区之间的关系
又称方法栈,线程私有的,线程执行方法是都会创建一个栈阵,用来存储局部变量表,操作栈,动态链接,方法 出口等信息.调用方法时执行入栈,方法返回式执行出栈.
11. 本地方法栈
与栈类似,也是用来保存执行方法的信息.执行Java方法是使用栈,执行Native方法时使用本地方法栈.
12. 堆
是被线程共享的一块内存区域, 创建的对象和数组都保存在 Java 堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域。
由于现代 VM 采用分代收集算法, 因此 Java 堆从 GC 的角度还可以细分为:
新生代(Eden 区、 From 幸存者区和 To 幸存者区)
老年代
永久区: jdk1.8以后,叫元空间,它使用的是直接内存,与新生代和老年代分开。这个区域是常驻内存的,用来存放jdk自身携带的class对象。
13. 解释内存中的栈(stack)、堆(heap)和方法区(method area)的用法。
栈的使用:
通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用JVM中的栈空间。
堆的使用:
通过new关键字和构造器创建的对象则放在堆空间,堆是垃圾收集器管理的主要区域。
方法区的使用:
方法区和堆都是各个线程共享的内存区域,用于存储已经被JVM加载的类信息、常量、静态变量、JIT编译器编译后的代码等数据;程序中的字面量如直接书写的100、"hello"和常量都是放在常量池中,常量池是方法区的一部分。
14. 堆和栈的区别
栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片;
堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片。
1. 功能不同
栈内存用来存储局部变量和方法调用,而堆内存用来存储Java中的对象。无论是成员变量,局部变量, 还是类变量,它们指向的对象都存储在堆内存中。
2. 共享性不同
栈内存是线程私有的。
堆内存是所有线程共有的。
3. 异常错误不同
如果栈内存或者堆内存不足都会抛出异常。
栈空间不足:java.lang.StackOverFlowError。堆空间不足:java.lang.OutOfMemoryError。
4. 空间大小
栈的空间大小远远小于堆的
15. 说一下 JVM由那些部分组成,运行流程是什么
JVM包含两个子系统和两个组件:
两个子系统为: ClassLoader(类加载器)、Execution engine(执行引擎);
两个组件为: Runtime data area(运行时数据区)、Native Interface(本地接口)
Class loader(类加载器): 根据给定的类名类加载class文件到Runtime data area中的method area.
Execution engine(执行引擎): 执行classes中的指令.
Native interface(本地接口): 与navtive libraries交互,是其他编程语言交互接口。
Runtime data area(运行时数据区域): 这就是我们常说的JVM的内存.
作用: 首先通过编译器把java代码转换成字节码, 类加载器(Class loader)在把字节码加载到内存中, 将其放在运行时数据区(Runtime data area)的方法区内, 而字节码文件只是JVM的一套指令集规范,并不能直接交给底层操作系统去执行, 因此需要特定的命令解析器执行引擎(Execution Engine), 将字节码翻译成底层系统指令,再交由CPU去执行, 而这个过程中需要调用其他语言的本地库接口(Native interface)来实现整个程序的功能.
16. 说一下JVM运行时数据区
程序计数器(Program Counter Register):
当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成; 为什么要线程计数器?因为线程是不具备记忆功能.
Java 虚拟机栈(Java Virtual Machine Stacks):
每个方法在执行的同时都会在Java 虚拟机栈中创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
栈帧就是Java虚拟机栈中的下一个单位.
本地方法栈(Native Method Stack):
与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;
Native 关键字修饰的方法是看不到的,Native 方法的源码大部分都是 C和C++ 的代码
Java 堆(Java Heap):
Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存。
方法区(Methed Area):
用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
17. 描述一下JVM加载class文件的原理机制?
Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。
1. 类加载器收到类加载的请求
2. 将这个请求向上委托给父类加载器去完成, 一直向上委托,直到启动类加载器
3. 启动类加载器检查是否能加载当前这个类, 能加载就结束, 使用当前的加载器,否则,抛出异常,通知子加载器进行加载.
4. 如何找不到就报错 ClassNotFound
18. Java程序运行机制详细说明
编写java源文件(.java)文件,java文件通过编译器变成了.class文件, java运行.class字节码文件时,会使用类加载器(ClassLoader)将这些.class文件加载到JVM中。将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构。
19. Java类加载器有哪些?
虚拟机设计团队把加载动作放到 JVM 外部实现,以便让应用程序决定如何获取所需的类, JVM 提供了 3 种类加载器:
启动类加载器(Bootstrap)
负责加载 JAVA_HOME\lib 目录中的, 或通过-Xbootclasspath 参数指定路径中的, 且被虚拟机认可(按文件名识别, 如 rt.jar) 的类。
扩展类加载器(Extension)
负责加载 JAVA_HOME\lib\ext 目录中的,或通过 java.ext.dirs 系统变量指定路径中的类库。
应用程序类加载器(Application)
负责加载用户路径(classpath)上的类库。JVM 通过双亲委派模型进行类的加载, 当然我们也可以通过继承 java.lang.ClassLoader实现自定义的类加载器。
20. GC是什么?为什么要有GC?
GC 是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或
者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java 提供的 GC 功能可以自动监测对象
是否超过作用域从而达到自动回收内存的目的,Java 语言没有提供释放已分配内存的显示操作方
法。
21. 你知道哪些JVM性能调优?
设定堆内存大小
-Xmx:堆内存最大限制。
设定新生代大小。 新生代不宜太小,否则会有大量对象涌入老年代
-XX:NewSize:新生代大小
-XX:NewRatio 新生代和老生代占比
-XX:SurvivorRatio:伊甸园空间和幸存者空间的占比
设定垃圾回收器 年轻代用 -XX:+UseParNewGC 年老代用-XX:+UseConcMarkSweepGC
22. GC常用算法
引用计数法: 记录每个对象 的引用次数,长时间没有被引用的对象就被清除掉。
复制算法: 复制算法最佳使用场景:对象存活度较低的时候 -> 新生区
好处:没有内存碎片
坏处:浪费内存空间,多了一半to空间永远是空的。
标记清除算法: 扫描这些对象: 对活着的对象进行标记,清除没有被标记的对象
优点: 不需要额外的空间。
缺点: 两次扫描,严重浪费时间,会产生内存碎片。
标记压缩: 标记 -> 清除 -> 压缩