jvm工作流程原理
- 其中方法区与堆会有垃圾存在需要GC去处理,其中方法区与堆是被所有线程共享的
- 方法区中存放静态变量、常量(字符串也是常量)、类(构造方法、常量池)、常量池
- 栈为引用堆中的实例对象,栈中引用的是堆中的地址,方法区存放变量、常量
- 计数器,每个线程都有一个计数器,是线程私有的
- 栈:包含8大基本类型+对象引用+实例方法
栈帧:
类加载器的反射机制
双亲委派机制
目的:为了更安全 APP--->EXT--->BOOT
- boot在rt jar包中
- exc在lib ext文件中
- 类加载器收到类加载的请求
- 将这个请求向上委托给父类加载器去完成,一直向上委托
- 启动加载器检查是否能够加载,能加载就结束,否则抛出异常,通知子加载器进行加载
- 重复步骤3
用的jvm是sun公司的Hotspot
堆
heap,一个jvm只有一个堆内存,堆内存的大小是可以调节的。堆中放类,方法,常量,变量保存所用引用类型的真实对象。
堆内存中细分为三个区域:
- 新生区
- 养老区
- 永久区
oom表示堆内存满了
JDK1.8以后永久区叫元空间
新生区
- 类:诞生和成长的地方甚至死亡
- 伊甸园,所有对象都是在伊甸园区new出来的
- 幸存者区(0,1)
永久区
用来存放JDK自身携带的class对象。Interface元数据,存放java运行时的一些环境或类信息,这个区域不存在垃圾回收,关闭虚拟机就会释放这个区域的内存。
OOM故障排除
内存快照分析工具,MAT,Jprofiler
MAT,Jprofiler作用
- 分析Dump内存文件,快速定位内存泄漏
- 获得堆中数据
- 获得大的对象
GC
jvm在进行GC时,并不是这三个区域统一回收,大部分时候,回收都是新生区
- 新生代
- 幸存区(交换form,to谁空谁是to)
- 老年区 GC两种类型:
- 轻GC(普通GC主要在新生区)
- 重GC(全局GC)
GC的算法哪些:
- 标记清除法 先标记在清除未标记的对象
- 好处:不需要额外的空间
- 坏处:两次扫描严重浪费时间,会产生内存碎片
- 标记整理 防止内存碎片再次扫描,向一端移动存活对象多了移动成本
- 复制算法
- 好处:没有内存的碎片
- 坏处:浪费了内存空间,多了一半空间永远是空to如极端情况100%存活率
- 复制算法最佳使用场景:对象存活度较低的时候;新生区
- 引用计数法
GC总结
内存效率:复制算法>标记清除算法>标记整理(时间复杂度) 内存整齐度:复制算法=标记整理>标记清除算法 内存利用率:标记整=标记清除算法>复制算法
GC分代收集 年轻代:存活率低,复制算法 老年代:存活率高,标记清除(到达一定数量次数)+标记压缩混合 实现