Site
Site
文章目录
  1. 内存模型
    1. 栈区
    2. 程序计数器
    3. 方法区
  2. 垃圾回收
    1. 垃圾收集器

JVM内存模型与垃圾回收

内存模型


Picture

  堆栈的分开设计

  1. 栈存储了处理逻辑,堆存储了具体的数据,这样隔离设计更为清晰
  2. 堆栈分离使得堆可以被多个栈共享
  3. 栈保存了上下文的信息,因此只能向上增长;而堆是动态分配的

  栈的大小可以通过-XSs设置,如果不足的话,会引起java.lang.StackOverflowError的异常

栈区

  线程私有,生命周期跟线程相同,每个方法执行的时候都会创建一个栈帧(stack frame)用于存放局部变量表,操作栈,动态链接,方法出口。

  存放对象实例,所有对象的内存都在这里分配。垃圾回收主要就是作用于这里。

  1. 堆的内存由-Xms指定,默认是物理内存的1/64;最大的内存由-Xmx指定,默认是物理内存的1/4。
  2. 默认空余的堆内存小于40%时,就会增大,直到-Xmx设置的内存。具体的比例可以由-XX:MinHeapFreeRatio指定。
  3. 空余的内存大于70%时,就会减少内存,直到-Xms设置的大小。具体由-XX:MaxHeapFreeRatio指定。
      因此一般都将这两个参数设置成一样大,避免JVM不断调整大小。

程序计数器

  这里记录了线程执行的字节码的行号,在分支,循环,跳转,异常,线程恢复等都依赖这个计数器。

方法区

  类型信息,字段信息,方法信息,其他信息。

垃圾回收

  在Java中,如果对象实体没有引用指向的话,存储该实体的内存便成为垃圾。JVM会有一个系统线程专门负责回收垃圾。垃圾同时包括分配对象内存间的碎片。
  判断对象可以回收的情况:

  1. 显示的把某个引用置位 NULL 或者指向别的对象
  2. 局部引用指向的对象
  3. 弱引用关联的对象

  目前JVM主要采取 Generational Collection 分代收集的方法进行回收,思想是把JVM分成不同的区域,每种区域使用不同的方法进行垃圾回收。它是Mark-Sweep标记-清除算法(会造成内存碎片),Copying 复制算法(不涉及对象的删除,将可用的对象从一个地方拷贝到另一个地方,因此适合大量对象回收,如新生代回收),Mark-Compact 标记-整理算法(适合解决碎片问题,但是会增加停顿)的合体。

堆内存分为3个区域:

  • 新生代(Young Generation):用于存放新创建的对象,采用复制回收方法,这里的垃圾回收叫做 Minor GC。
  • 年老代(Old Generation):这些对象垃圾回收的频率较低,采用的标记整理方法,这里的垃圾回收叫做 Major GC。
  • 永久代(Permanent Generation):存放 Java 本身的一些数据,当类不再使用时,也会被回收。

垃圾收集器

  1. 串行收集器 Serial:这种收集器就是以单线程的方式收集,垃圾回收的时候其他线程也不能工作。
  2. 并行收集器 Parallel:以多线程的方式进行收集。
  3. 并发标记清除收集器 Concurrent Mark Sweep Collector, CMS:大致的流程为:初始标记–并发标记–重新标记–并发清除
  4. G1收集器 Garbage First Collector:大致的流程为:初始标记–并发标记–最终标记–筛选回收
支持一下
扫一扫,支持xfan
  • 微信扫一扫
  • 支付宝扫一扫