栈:也叫方法栈,存储局部变量表,动态链接,方法出口等信息,调用方法执行入栈,方法返回执行出栈。
本地方法栈:与方法栈类似,区别是执行native方法使用的是本地方法栈,执行java方法使用的是方法栈。
(注:native方法即使用native关键字修饰的java方法,目的在于与操作系统进行交互,调用操作系统语言程序。)
程序计数器:保存当前线程所保存的字节码位置,每个线程工作时都有一个独立的计数器,程序计数器只为java方法服务,执行native方法时,程序计数器为空。
堆:jvm内存管理中最大的一块,用于存放对象的实例,当对空间不足时,会抛出OOM异常(java.lang.OutOfMemoryError),jvm把堆内存进行分代管理,由垃圾回收器进行对象的回收管理。
方法区:又叫非堆区,用于存储已被虚拟机加载的类信息、常亮、静态变量、编译器优化后的代码等数据,jdk1.7的永久代和1.8的materspace都是方法区的一种实现。
栈、本地方法栈、程序计数器是线程独占的。
堆、方法区是线程共享的。
JMM需要保证原子性、可见性、有序性,通过以下四种方式:
1、基本数据类型读或写(long、double除外):是原子性的。
2、synchronized:通过java的两个高级字节码指令monitorenter和monitorexit来保证原子性,
3、volatile:
4、happens-bofore原则:
深绿色表示加载过程,浅绿色表示生命周期。
加载:通过类的完全限定名找到字节码文件,通过字节码文件创建class对象。
验证:图中始终验证方法。
准备:为static修饰的变量分配内存,初始值0或者null。(final不分配,因为在编译时已经分配)
解析:图中。
初始化:看图中解释,若类的父类没有初始化,则先初始化父类的静态块和静态变量,只有对类的主动使用时才会初始化。
使用:实例化。
卸载:java前三种类加载器的加载的类不会被卸载,用户自定义类加载器加载的类才会被卸载。
类加载器:启动类加载器、扩展类加载器、应用/系统加载器、用户自定义加载器。
双亲委派模式好处:
年轻代:大部分对象会在Eden区生成,Eden区满时,会在s1和s2中交替保存,达到一定次数对象会晋升到老年代。
老年代:存储由年轻代晋升到老年代存储时间较长的内存对象。
永久代:主要保存类信息等内容。(这里只是一种划分方式,并不是特指1.7 PermGen/1.8 Metaspace)
判断算法:
清除算法:
jvm提供的年轻代回收算法属于复制算法,CMS、G1,ZGC属于标记清除算法。
CMS是标记清除算法,JDK1.7之前的默认垃圾回收算法,并发收集,停顿小。
G1算法JDK1.9之后默认回收算法,特点是保持高回收率的同时,减少停顿。
G1可以通过设置JVM参数设置rejion(区)的大小,范围是1~32M,还可以设置期望的最大停顿时间。
ZGC针对大内存的回收,可以控制在10ms以内的停顿。
ZGC GC过程:
1、JVM内存模型、JMM内存模型
2、类加载过程、双亲委派机制
3、原子性、可见性、有序性的保证机制
4、G1适合对最大延迟有要求的场合,ZGC适合64位对大内存有要求的场合
5、垃圾回收的并发数,偏向锁的设置
1、栈上分配释放压力,如何编写适合内联优化的代码
2、经常fullGC的问题,内存泄漏问题
3、
4、
1、见上
2、年轻代晋升、老年代空间不足、永久代空间不足
3、见上
4、见上
5、见上
6、见上
7、强制主内存读写同步,防止指令重排序
10、
强引用:不会被GC回收
弱引用:每次GC都会被回收
虚引用:必须和引用兑现联合使用,跟总一个对象被垃圾回收的过程
软引用:空间不足会被GC回收
11、
JMC:飞行计数器
MAT:堆分析工具
JStack:线程分析工具
课程链接:https://kaiwu.lagou.com/course/courseInfo.htm?courseId=1&sid=3-PC_banner-0