聊聊JVM[深入了解jvm各模块]

本篇详细聊聊Jvm 虚拟机栈,堆,以及GC

本文基于jdk1.8

  • 虚拟机栈 VS 堆
    • 栈管运行,堆管内存 (这个不一定全部,但是一定程度上也说明了栈堆的区别)

虚拟机栈 (VM Stack)

  • 先放一张结构图

  • 虚拟机栈属于非共享区域

  • 每个线程都有一个自己的栈空间

    • 可以通过-Xss20m(将栈空间设置成最大为20m)
  • 栈的主要构成就是栈帧。一个方法的调用就是一个栈帧。

  • 栈帧的里面的内容主要包括

    • 局部变量表
      • 编译的时候就已经确定了,这里涉及的内容不会改变
    • 操作栈
      • 简单理解就是一个方法里面的代码逻辑 也是基于栈来的。(更细维度的栈)
      • 描述的是方法的具体执行
    • 动态链接
      • 简单理解就是对于对象,栈帧只保存其引用。其具体所在位置在堆中。
    • 方法返回地址
      • 方法退出有两种:
        • 正常退出。如果有返回结果,则会把结果压入到上一个栈帧的操作栈中
        • 异常退出。抛异常,由上层栈帧做异常处理
    • 额外信息
  • 因为在栈帧内存储的是局部变量,操作栈,动态链接都是在编译是确定的,所以一个栈帧的大小是固定的。

堆 (Heap)

  • 主要存放各种实例对象
  • 具体抽象结构如下
  • 分区
    • Young
      • Eden + survivor0+survivor1 (默认比例8:1:1)
      • 使用的是复制GC(minor GC), 每次总有一块Survivor 是空闲的。 90%可使用
    • Old
      • minorGC超过(15次)存活的对象,或者是超大对象
      • FullGC.

GC(垃圾回收) Garbage Collection

先聊下那些需要被回收
  • 虚拟机栈程序计数器本地方法栈。这三个都是随线程而生,随线程而灭, 所以不需要考虑过多考虑回收
  • 堆与方法区
    复制 (Copying)
  • 将内存分为两块(A,B),平时只用一块A。GC的时候,将使用的一块A中GCROOTS可以查到的对象紧密复制到另一块B,然后将之前板块A全部清空。
  • 优点:效率高
  • 弊端:内存只能用一半
标记整理 (Mark-Compact)
  • 过程
    • 标记: 先通过GCROOTS到达的对象,
    • 整理:移动所有标记存活的对象,重新排列。然后将内存地址值之后的内存清空
  • 优点:内存使用率高,无内存碎片
  • 弊端:需要暂停程序, 效率交Copying慢
    标记清除 (Mark-Sweep)
  • 过程
    • 标记: 先通过GCROOTS到达的对象,
    • 清除:清楚未被标记的对象。
  • 优点:内存使用率高。
  • 缺点:
    • 会产生内存碎片,逐渐的连续的可用空间越来越小,导致gc越来越频繁
    • 需要暂停程序
分代收集
  • 新生代(copying)
  • 老年代(标记整理/标记清除)

垃圾回收器

  • jdk8 默认的是Parallel Scavenge + ParallelOld

  • Serial(串行收集器)

    • 单线程 stop the world
    • 复制算法
  • ParNew(Serial的多线程版本)

    • 复制算法
  • Parallel Scavenge

    • 并行多线程收集器
    • 复制算法
    • 有自调节
  • SerialOld

    • 串行老年代版本
    • 标记/整理算法
  • ParallelOld

    • 并行老年代版本
    • 标记/整理算法
  • CMS

    • 以最短回收停顿时间为目标,使用标记-清除算法
    • 过程:
      • 初始标记:stop the world 标记GC Roots能直接关联到的对象
      • 并发标记:进行GC Roots Tracing
      • 重新标记:stop the world;修正并发标记期间因用户程序继续运作而导致标记产生变动的 那一部分对象的标记记录
      • 并发清除:清除对象
    • 优点:并发收集,低停顿
    • 缺点:
      • 对CPU资源敏感
      • 无法处理浮动垃圾(并发清除 时,用户线程仍在运行,此时产生的垃圾为浮动垃圾)
      • 产生大量的空间碎片
  • G1

    • 并行与并发
    • 分代收集
    • 面向服务端应用,将整个堆分为大小相同的region

JVM 一些调优参数

  • -Xms512m (堆初始大小)
  • -Xmx1024m(堆最大大小)
  • -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m. 调整元空间大小(存储java类信息)
  • -Xss128m (虚拟机栈大小)
  • -XX:NewRatio=4 (young:old=1:4) 默认是2