JVM学习笔记

226 阅读4分钟

== 1.运行时数据区域 ==

Java 8 虚拟机规范

深入理解Java虚拟机

[[File:https://tva1.sinaimg.cn/large/007S8ZIlgy1gfc0d737m7j30e40femyx.jpg|frame|none|alt=|caption ]]

=== 1.程序计数器 ===

Program Counter Register
指向当前线程正在执行的字节码指令的地址行号

=== 2.虚拟机栈 ===

在执行每个方法的时候,JVM都会同步创建一个栈帧

生命周期随方法的调用而创建,随方法的结束而销毁

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/Screen Shot 2020-05-16 at 22.53.07.png|frame|none|alt=|caption ]]

==== 1.局部变量表 ====

==== 2.操作数栈 ====

==== 3.动态链接 ====

==== 4.方法出口 ====

=== 2.本地方法栈 ===

StackOverflowError

OutOfMemoryError

与虚拟机栈类似,调用非Java 方法

=== 3.方法区 ===

Method area
* 参数控制 ** -XX:MetaspaceSize=256M ** -XX:MaxMetaspaceSize=256M *** 默认不限制大小 ** -XX:MinMetaspaceFreeRatio=40 *** 最小空闲比,当 Metaspace 发生 GC 后,会计算 Metaspace 的空闲比,如果空闲比(空闲空间/当前 Metaspace 大小)小于此值,就会触发 Metaspace 扩容。默认值是 40 ,也就是 40% ** -XX:MaxMetaspceFreeRatio=70 *** 最大空闲比,当 Metaspace 发生 GC 后,会计算 Metaspace 的空闲比,如果空闲比(空闲空间/当前 Metaspace 大小)大于此值,就会触发 Metaspace 释放空间。默认值是 70 ,也就是 70% * 存放类的元数据信息 * 字符串常量池,静态变量已移到Heap中

=== 4.Heap(堆) ===

==== 1.JVM内存模型 JMM ====

Jdk1.8之前

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/Screen Shot 2020-05-17 at 10.40.28.png|frame|none|alt=|caption ]]

Jdk1.8及以上

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/Screen Shot 2020-05-17 at 10.43.53.png|frame|none|alt=|caption ]]

Meta space 不算JVM内存,仅根据机器的内存大小

  • 参数 ** -Xmx:125m ** -Xms:125m ** -Xmn:50 *** 设置年轻代的大小 ** -XX:NewRatio=2 *** 新生代(eden+2*s)和老年代的比值 *** 2 表示 新生代:老年代=1:4,即年轻代 = Heap的1/5 ** -XX:SurvivorRatio=8 *** 设置两个Survivor和eden的比 *** 8 表示 两个Survivor:eden=2:8

==== 2.Thread Local Allocation Buffer(TLAB) ====

线程私有的的分配缓冲区,提升对象分配时的效率

  • 参数 ** -Xss:128k

=== 4.运行池常量池 ===

runtime constant pool

outOfMemoryError 异常

* 每个类都维护一个常量池 * 是class 文件中每一个类或接口的常量池表(constant_pool)的运行时表示形式 ** constant_pool 存放编译期生成的各种 '''字面量''' 与 '''符号引用''' *** 字面量(Literal):文本字符、被声明为finalde 的常量值 *** 符号引用(Symbolic Reference): * 每一个运行时常量池都在Java 虚拟机的 '''方法区 '''中分配 * 在加载类和接口到虚拟机后,就创建对应的运行时常量池

==== 字符串常量池 ====

String str1 = “abc”;
String str2 = “abc”;
String str3 = new String(“abc”);
String str4 = new String(“abc”);

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/Screen Shot 2020-05-20 at 08.47.18.png|frame|none|alt=|caption ]]

== 2.垃圾回收 ==

=== 1.对象的分配 ===

  • TLAB 分配
  • Eden 区分配
  • 大对象直接进入老年代 ** -XX:PretenureSizeThreshold
  • 长期存活的对象进入老年代 ** -XX:MaxTenuringThreshold=1
  • 空间分配担保

=== 2.回收算法 ===

==== 1.分代收集 ====

==== 2.标记-清除算法(Mark-Sweep) ====

缺点:

  • 1.执行效率不高
  • 2.内存空间的碎片化问题

==== 3.标记-复制算法 ====

==== 4.标记-整理算法 ====

==== 5.safepoint(安全点) ====

=== 3.回收器 ===

==== 1.Serial 收集器 ====

单线程工作

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/IMG_E45554563F5F-1.jpeg|frame|none|alt=|caption ]]

==== 2.ParNew ====

  • 是Serial收集器的多线程并行版本
  • ParNew是CMS 默认的 新生代垃圾收集器

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/IMG_D79A8E9FDA43-1.jpeg|frame|none|alt=|caption ]]

参数

  • -XX:SurvivorRatio
  • -XX:PretenureSizeThreshold
  • -XX:HandlePromotionFailure
  • -XX:+/-UseParNewGC ** 强制开启或禁用 ParNew收集器
  • -XX:ParallelGCThreads ** 限制垃圾收集的线程数

==== 3.Parallel Scavenge 收集器 ====

  • 新生代收集器

  • 基于标记-复制算法

  • Parallel Scavenge 目标是达到一个可控制的吞吐量(Throughput),CMS 尽可能地缩短垃圾收集时用户线程的停顿时间

    吞吐量 = \frac{运行用户代码时间}{运行用户代码时间 + 运行垃圾收集时间}

==== 4.Serial Old 收集器(Ps MarkSweep) ====

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/IMG_42A8EE5708AA-1.jpeg|frame|none|alt=|caption ]]

  • 老年代
  • 单线程
  • 标记-整理算法
  • 可与Parallel Scavenge 搭配使用

==== 5.Parallel Old 收集器 ====

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/IMG_0ADFA4A040C7-1.jpeg|frame|none|alt=|caption ]]

  • 是Parallel Scavenge 收集器老年代版
  • 多线程并发收集
  • 基于标记-整理算法实现

==== 6.CMS 收集器 ====

[[File:/Users/luchao/Documents/笔记/1_每日进步/8-JVM/img/IMG_7D708CBD5F8B-1.jpeg|frame|none|alt=|caption ]]

  • 以获得最短回收停顿时间为目标的收集器(关注响应时间)
  • 标记-清理算法
  • 资源敏感 ** 默认回收线程数= (处理器核心数量 + 3)/4
  • 存在浮动垃圾(Floating Garbage)
  • 过程 ** 初始标记(CMS initial mark) *** 标记GC root能直接关联的对象,速度很快 ** 并发标记(CMS concurrent mark) ** 重新标记(CMS remark) ** 并发清除(CMS concurrent sweep)

参数

  • -XX:+UseConcMarkSweepGC

==== 7.G1 收集器 ====

  • Region 的内存布局 ** Humongous对象存储大对象(超过Region容量的一半的对象即可判定为大对象) ** --XX:G1HeapRegionSize(1MB~32MB)
  • --XX:MaxGCPauseMillis 指定允许的收集停顿时间,默认200毫秒

== 3.练习 ==