面试-java虚拟机
2021/5/23 1:25:10
本文主要是介绍面试-java虚拟机,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
JVM运行时数据区域有哪些?
JDK1.8 之前
程序计数器, Java 虚拟机栈, 本地方法栈, 堆, 方法区, 运行时常量池, 直接内存
JDK1.8 之后
程序计数器, Java 虚拟机栈, 本地方法栈, 堆, 元空间, 直接内存
JVM 运行是数据区域哪些是私有的,哪些是共享的?
线程私有的:
- 程序计数器
- 虚拟机栈
- 本地方法栈
线程共享的:
- 堆
- 方法区
- 直接内存 (非运行时数据区的一部分)
JVM 的堆内存被划分成那几块区域,比例是如何的?
在 JDK 7 版本及 JDK 7 版本之前,堆内存被通常被分为下面三部分:
- 新生代内存(Young Generation)
- 老生代(Old Generation)
- 永生代(Permanent Generation)
老年代与新生代比例为 2 : 1。新生代分为一个Eden和两个 Survivor 区域,比例为8:1:1。
在 JDK1.8 之后,永生代(Permanent Generation)被移除,取而代之的是元空间
对象经过几次GC之后可以从新生代变成老生代?
默认 15 次.
对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s0 或者 s1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold
来设置。
对象创建过程经历哪些步骤
- 类加载检查
- 分配内存
- 初始化零值
- 设置对象头
- 执行 init 方法
如何判断哪些对象已经死亡?
1.引用计数法
给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加 1;当引用失效,计数器就减 1;任何时候计数器为 0 的对象就是不可能再被使用的。
这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是它很难解决对象之间相互循环引用的问题。
2.可达性分析算法
这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。
常见垃圾收集算法有哪些?
- 标记-清除算法
- 复制算法
- 标记-整理算法
- 分代收集算法
垃圾收集器有哪些?(最少写5个)
-
Serial 收集器
-
ParNew 收集器
-
Parallel Scavenge 收集器
-
Serial Old 收集器
-
Parallel Old 收集器
-
CMS 收集器
-
G1 收集器
类加载过程
加载
- 通过全类名获取定义此类的二进制字节流
- 将字节流所代表的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
验证
1. 文件格式验证 2. 元数据验证 3. 字节码验证 4. 符号引用认证
准备
为类变量分配内存并设置类变量初始值
解析
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行。
初始化
初始化阶段是执行类构造器 <clinit> ()
方法的过程
JVM 中有哪些类加载器
JVM 中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader 其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader
:
- BootstrapClassLoader(启动类加载器) :最顶层的加载类,由 C++ 实现,负责加载
%JAVA_HOME%/lib
目录下的 jar 包和类或者或被-Xbootclasspath
参数指定的路径中的所有类。 - ExtensionClassLoader(扩展类加载器) :主要负责加载目录
%JRE_HOME%/lib/ext
目录下的 jar 包和类,或被java.ext.dirs
系统变量所指定的路径下的 jar 包。 - AppClassLoader(应用程序类加载器) :面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
解释一下双亲委派模型
每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用 双亲委派模型 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。加载的时候,首先会把该请求委派该父类加载器的 loadClass()
处理,因此所有的请求最终都应该传送到顶层的启动类加载器 BootstrapClassLoader
中。当父类加载器无法处理时,才由自己来处理。当父类加载器为 null 时,会使用启动类加载器 BootstrapClassLoader
作为父类加载器。
双亲委派模型的好处
双亲委派模型保证了Java程序的稳定运行,可以避免类的重复加载(JVM 区分不同类的方式不仅仅根据类名,相同的类文件被不同的类加载器加载产生的是两个不同的类),也保证了 Java 的核心 API 不被篡改。如果没有使用双亲委派模型,而是每个类加载器加载自己的话就会出现一些问题,比如我们编写一个称为 java.lang.Object
类的话,那么程序运行的时候,系统就会出现多个不同的 Object
类。
如果我们不想用双亲委派模型怎么办?/如何破坏双亲委派机制?
为了避免双亲委托机制,我们可以自己定义一个类加载器,然后重写 loadClass()
即可。
如何自定义类加载器
除了 BootstrapClassLoader
其他类加载器均由 Java 实现且全部继承自java.lang.ClassLoader
。如果我们要自定义自己的类加载器,很明显需要继承 ClassLoader
。
如果需要设置 JVM 分配最小2 GB 和最大5 GB 的堆内存大小,参数如何写?
-Xms2G -Xmx5G
JDK 中看出所有 Java 进程使用哪个命令?
jps
监视虚拟机各种运行状态信息可以使用哪个命令?
jstat
试试查看和调整虚拟机各项参数使用哪个命令
jinfo
监视视本地及远程服务器的 java 进程的内存使用情况使用什么工具
jconsole
这篇关于面试-java虚拟机的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现