前言
记录总结一下 java 虚拟机的部分知识,知识主要来自于书籍《深入理解 java 虚拟机》。
组织形式会以小标题 & 内容解答组成。
内存管理机制
虚拟机内存如何划分
主要有程序计数器,虚拟机栈,本地方法栈,Java 堆,方法区
- 程序计数器:当前线程执行的字节码行号指示
- 虚拟机栈:java 方法执行的信息(局部变量表,操作栈,动态链接,方法出口等)
- 本地方法栈:native 方法执行的信息
- Java 堆:存放对象实例。垃圾收集主要区域,所有线程共享
- 方法区:类信息,常量,静态变量,即时编译后代码等
内存溢出的情况
- 虚拟机栈,本地方法栈无法申请到更多内存。
- Java 堆没有内存完成实例分配或者堆无法扩展。
- 方法区无法满足内存分配需求,运行时常量池超出内存限制。
- 直接内存大于物理内存限制
判断对象存活方法
- 引用计数法:对象有引用到的地方就计数+1,引用失效-1。不能解决循环引用的问题
- 根搜索算法:Gcroot 对象为起点,向下搜索,不可达的可判定为可回收
引用分类:强引用,软引用,弱引用,虚引用
垃圾回收算法
- 标记清除法:标记所有要回收的对象,然后统计清除。(效率不高,会产生不连续内存碎片)
- 复制算法:分两块内存,一块用完了将活着的对象复制到另一块,然后清除这一块
- 标记-整理算法:标记清除后将对象都整理到一端
- 分代收集算法:java 堆分为新生代(一个 Eden 区,2 个 Survivor 区,8:1:1)和老年代,新生代使用复制算法,老年代使用标记清除
垃圾收集器
- Serial 收集器:单线程,client 模式新生代收集器
- ParNew 收集器:多线程版 Serial 收集器,server 模式下首选新生代收集器
- Parallel Scavenge 收集器:多线程新生代收集器,控制吞吐量
- CMS 收集器:以获取最短回收停顿时间为目标
- G1 收集器:基于标记-整理
内存分配与回收策略
- 对象优先在新生代 Eden 区中分配
- 大于 PretunureSizeThreshold 设置的大对象直接在老年代中分配
- 长期存活的对象将进入老年代,每次 minor gc 后年龄计数器+1,直到大于年龄阈值
- 动态对象年龄判定,相同年龄对象大禹 survivor 空间一半,大于等于该年龄的对象进入老年代
- 晋升到老年代的空间大于老年代剩余空间,则 full gc;小于的话如果允许担保失败,则 minor gc,否则 full gc;
jdk 命令行工具
- jps:列出正在允许的 java 虚拟机进程和主类名
- jstat:监控虚拟机各种允许状态(-gc,-class)
- jinfo:实时查看调整虚拟机参数
- jmap:生成堆转储快照
- jhat:分析 jmap 生成的快照
- jstack:生成虚拟机当前时刻线程快照
jdk 可视化工具
- jconsole
- jvisualvm
虚拟机执行子系统
版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下