Java虚拟机

《深入理解java虚拟机》学习篇

Posted by 甘家城 on 2020-09-13 Viewed times

前言

记录总结一下java虚拟机的部分知识,知识主要来自于书籍《深入理解java虚拟机》。
组织形式会以小标题 & 内容解答组成。

内存管理机制

虚拟机内存如何划分

主要有程序计数器,虚拟机栈,本地方法栈,Java堆,方法区

  • 程序计数器:当前线程执行的字节码行号指示
  • 虚拟机栈:java方法执行的信息(局部变量表,操作栈,动态链接,方法出口等)
  • 本地方法栈:native方法执行的信息
  • Java堆:存放对象实例。垃圾收集主要区域,所有线程共享
  • 方法区:类信息,常量,静态变量,即时编译后代码等

内存溢出的情况

  • 虚拟机栈,本地方法栈无法申请到更多内存。
  • Java堆没有内存完成实例分配或者堆无法扩展。
  • 方法区无法满足内存分配需求,运行时常量池超出内存限制。
  • 直接内存大于物理内存限制

判断对象存活方法

  • 引用计数法:对象有引用到的地方就计数+1,引用失效-1。不能解决循环引用的问题
  • 根搜索算法:Gcroot对象为起点,向下搜索,不可达的可判定为可回收
    引用分类:强引用,软引用,弱引用,虚引用

垃圾回收算法

  • 标记清除法:标记所有要回收的对象,然后统计清除。(效率不高,会产生不连续内存碎片)
  • 复制算法:分两块内存,一块用完了将活着的对象复制到另一块,然后清除这一块
  • 标记-整理算法:标记清除后将对象都整理到一端
  • 分代收集算法:java堆分为新生代和老年代,新生代使用复制算法,老年代使用标记清除

垃圾收集器

  • 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

虚拟机执行子系统