2021面试-JVM
文章目录
JVM内存模型
程序计数器(线程私有)
虚拟机栈(线程私有)
本地方法栈(线程私有)
堆 (线程共享)
方法区/永久代(线程共享)
- 用于存储JVM加载的类信息。常量和静态变量,即时编译后的代码数据。
- 包含运行时常量池,用于存放各种字面量和符号引用。
MinorGC的过程(复制-清空-互换)
- MinorGC采用复制算法
- eden,from复制到to区 , 年龄+1
- 清空eden,from
- to和from互换
MajorGC的过程:
产生OOM:
- 永久带,GC不会在主程序运行期间对永久带进行清理,所以随着加载class的增多而胀满,最终抛出OOM
- 老年代,当有大的对象老年代装不下的是就会抛出OOM
老年代:
- 存放应用周期长的内存对象
垃圾回收
如何确定对象已死?
垃圾收集算法:
垃圾收集器:
- Serial
- ParNew
- Parallel Scavenge
- 多线程复制算法、高效
- 利用高吞吐量高效的利用cpu时间
- Serial Old
- Parallel Old
- 多线程, 标记整理算法
- CMS - Concurrent Mark Sweep
- 多线程,标记清除算法
- G1: Garbage first
多路复用IO模型
相关参数:
堆设置
- -xms:初始堆大小
- -Xmx:最大堆大小
- -XX:NewSize=n:设置年轻代大小
- -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
- -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
- -XX:MaxPermSize=n:设置持久代大小
收集器设置
- -XX:+UseSerialGC:设置串行收集器
- -XX:+UseParallelGC:设置并行收集器
- -XX:+UseParalledlOldGC:设置并行年老代收集器
- -XX:+UseConcmarkSweepGC:设置并发收集器
垃圾回收统计信息
- -XX:+PrintGC
- -XX:+PrintGCDetails
- -XX:+PrintGCTimeStamps
- -Xloggc:filename
并行收集器设置
- -XX:ParallelGCThreads=n:设置并行收集器收集时使用的cpu数。并行收集线程数。
- -XX:MaxGCPauseMillis=n:设置并行收集最大暂停时间
- -XX:GCTimeRatio=n:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)
并发收集器设置
- -XX:+CMSIncrementalMode:设置为增量模式。适用于单cpu情况。
- -XX:ParallelGCThreads=n:设置并发收集器年轻代收集方式为并行收集时,使用的cpu数。并行收集线程数。
类加载-反射
JVM类加载机制
- 加载-验证-准备-解析-初始化
双亲委派:
- 当一个类收到类加载请求,它首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,
- 每一层类加载器都是如此。
- 只有当父类反馈自己无法完成这个请求的时候,子类加载器才会尝试自己去加载。
- 目的是:保证不同的类加载最终得到的是同一个object对象。
双亲委派的几个好处:
- 可以避免类的重复加载
- 保证了安全性
双亲委派 “父子加载器”之间是继承关系吗?
双亲委派模型中,类加载器之间的父子关系一般不会以继承的关系来实现,而都是使用组合的关系来复用父加载器的代码
⭐️ 双亲委派是如何实现的 ?
- 先检查类是否已经被加载过
- 若没有加载则调用父类加载器的loadClass()进行加载
- 若父类加载器为空,则默认使用启动类加载器作为父加载器
- 若父类加载失败,抛出ClassNotFoundException异常后,在调用自己的findClass()进行加载
如何主动破坏双亲委派机制:
双亲委派被破坏的列子
-
- 双亲委派出现之前:JDK1.2之后才引入的,在这之前是没有遵守的
-
- JNDI,JDBC等需要加载SPI接口实现类的情况。
-
- 为了实现热插拔热部署的工具。
-
- Tomcat等容器的出现
-
- Osgi,Jigsaw等模块化技术的应用
Person p = new Person()在内存中发生了什么?
- 将Person.class文件加载进内存中。
- 在栈中为p开辟一个变量空间
- 在堆中为对象分配空间
- 对对象中的成员变量进行初始化
- 调用静态代码块,非静态代码块对象进行初始化(没有就不执行)
- 调用构造方法对对象进行初始化,对象初始化完毕
- 将对象的内存地址赋值给p变量,让p变量指向该对象。
什么情况下创建的对象不在堆中?
- jit编译器下的逃逸分析算法会分析类使用情况
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。