一、说一说JVM的内存模型
JVM的内存区域划分分为四个区域:程序计数器,栈,堆,方法区(现在也叫元数据区)。
二 、JAVA类加载的全过程是怎样的?什么是双亲委派机制?有什么作用?一个对象加载到JVM,再到被GC清除,都经历了什么过程?
加载 - 验证 - 准备 - 解析 - 初始化
JAVA的类加载器: AppClassloader -> ExcClassloader -> BootStrap Classloader
每种类加载器都有他自己的加载目录
JAVA中的类加载器: AppClassLoader, ExtClassLoader ->SecureClassLoader -> ClassLoader
每个类加载器对他加载过的类 都有一个缓存的。
双亲委派:加载 -> 连接-> 初始化
加载: 把Java的字节码数据加载到JVM内存当中,并映射成JVM认可的数据结构。
连接:分为三个小的阶段
1.验证: 检查加载到的字节信息是否符合JVM规范。
- 准备:创建类或接口的静态变量,并赋初始值 半初始化状态
- 解析: 把符号引用转为直接引用
GC如何判断对象可以被回收
- 引用计数法:每个对象有一个引用计数属性, 新增一个引用时计数加1,引用释放时计算减1,计数为0可以回收
- 可达性分析法: 从GC Roots开始向下搜索,搜索所走过的路径成为引用链。当一个对象到达GC Roots 没有任何引用链相连时,则证明此对象是不可用的,那么虚拟机就判断是可回收对象
GC Roots的对象有
- 虚拟机栈(栈帧中的本地变量表) 中引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
- 本地方法栈中JNI(即一般说的Native方法)引用的对象
Java类加载器
JDK自带有三个类加载器: bootstrap ClassstrapLoader、ExtClassLoader、AppClassLoader
BootStrapClassLoader是ExtClassLoader的父类加载器,默认负责加载%JAVA_HOME%lib下的jar包和class文件
ExtClassLoader是AppClassLoader的父类加载器,负责加载%JAVA_HOME%/lib/ext文件夹下的jar包和class类。AppClassloader是自定义类加载器的父类,负责加载classpath下的类文件。系统类加载器,线程上下文加载器。
继承Classloader实现自定义加载器。
JVM中那些可以作为gc root
什么是gc root JVM在进行垃圾回收时,需要找到“垃圾”对象,也就是没有被引用的对象
,但是直接找“垃圾”对象是比较耗时的,所以反过来,先找“非垃圾”对象,也就是正常对象,那么就需要从某些“根“开始去找,根据这些”根“的引用路径找到正常对象,而这些”根“有一个特征,就是它只会引用其他对象,而不会被其他对象引用 例如 栈中的本地变量, 方法区中的静态变量, 本地方法栈中的变量,正在运行的线程等可以作为gc root
JVM哪些是线程共享的
你们项目如何排查JVM问题
对于还在正常运行的系统
可以使用jmap来查看JVM中各个区域的使用情况
可以通过stack来查看线程的运行情况,比如哪些线程阻塞、是否出现了死锁
可以通过jstate命令来查看垃圾回收的情况,,特别是fullgc,如果发现fullgc比较频繁,那么就得进行调优了
通过各个命令的结果,或者jvisualvm等工具来进行分析
⾸先,初步猜测频繁发送fullgc的原因,如果频繁发⽣fullgc但是⼜⼀直没有出现内存溢出,那么表
示fullgc实际上是回收了很多对象了,所以这些对象最好能在younggc过程中就直接回收掉,避免这
些对象进⼊到⽼年代,对于这种情况,就要考虑这些存活时间不⻓的对象是不是⽐较⼤,导致年轻
代放不下,直接进⼊到了⽼年代,尝试加⼤年轻代的⼤⼩,如果改完之后,fullgc减少,则证明修改有效。
同时,还可以找到占⽤CPU最多的线程,定位到具体的⽅法,优化这个⽅法的执⾏,看是否能避免
某些对象的创建,从⽽节省内存
对于已经发⽣了OOM的系统:
- ⼀般⽣产系统中都会设置当系统发⽣了OOM时,⽣成当时的dump⽂件(-
XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/base)
- 我们可以利⽤jsisualvm等⼯具来分析dump⽂件
- 根据dump⽂件找到异常的实例对象,和异常的线程(占⽤CPU⾼),定位到具体的代码
- 然后再进⾏详细的分析和调试
总之,调优不是⼀蹴⽽就的,需要分析、推理、实践、总结、再分析,最终定位到具体的问题
JVM的5种垃圾回收算法、垃圾回收机制与总结
- 引用技术算法
- 复制算法
- 标记清除算法
- 标记整理(压缩)算法
- 分代收集算法
一个对象从加载到JVM,再到被GC清除,都经历了什么阶段
method {ClassLoaderDemo1 c =- new ClassLoaderDemo1(); c.xxx} GC
- 用户创建一个对象, JVM首先需要到方法区去找对象的类型信息,然后再创建对象
- JVM要实例化一个对象,首先要在堆当中创建一个对象。-》半初始化状态
- 对象首先会分配再堆内存中新生代的Eden,然后经过一次Minor GC,对象如果存活,就会进入S区,在后续的每次GC中,对象会一直存活,就会在S区来回拷贝,每移动一次,年龄就+1 多大年龄才会移入老年代?年龄最大15 超过1定年龄后,对象转入老年代
- 当方法执行结束后,栈中的指针会先移除掉
- 堆中的对象,经过full GC,就会被标记为垃圾,然后被GC线程清清理掉。