Loading

JVM 内存管理

date: 2020-10-29 16:30:00
updated: 2020-10-29 17:10:00

JVM 内存管理

参考文档

1. 堆和栈

JVM内存划分:

  1. 寄存器(程序计数器PC拿到指令地址,放入指令寄存器IR中,cpu执行指令)
  2. 本地方法区
  3. 方法区
  4. 栈内存(stack)
    • 由编译器自动分配,存放函数的参数值,局部变量的值(定义在方法中的都是局部变量,方法外的是全局变量,for循环内部也是局部变量)
    • 先加载函数才能进行局部变量的定义,所以方法先进栈,再定义变量,变量离开作用域后释放,生命周期都很短
  5. 堆内存(heap,不是数据结构中的堆)
    • 由程序猿分配释放,如果程序猿不释放,程序结束时由GC回收
    • 存储的是数组和对象,凡是new的都在堆中,实体(对象)里面封装了多个数据,一个数据消失,实体不会消失,还可以用,所以堆不会随时释放,会由GC不定时回收

int[] arr = new int[3];
主函数进栈 -> 在栈中定义一个 arr 变量 -> 在堆里通过new开辟一个空间,这个空间会产生一个地址,这个地址下的所有所有会进行初始化 -> 把内存的地址赋值给 arr
int[] arr = null; arr不做任何指向,null的作用就是取消引用数据类型的指向

1.1 堆

堆又分为

  • 新生代
    • 新生代又被进一步划分为Eden和Survivor区,最后Survivor由FromSpace和ToSpace组成
    • 新建的对象都是由新生代分配内存
    • 新生代大小可以由-Xmn来控制,也可以用-XX:SurvivorRatio来控制Eden和Survivor的比例
  • 老年代
    • 用于存放新生代中经过多次垃圾回收仍然存活的对象

堆结构

堆结构

1.2 栈

每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,用于存放此次方法调用过程中的临时变量、参数和中间结果

2. GC

  1. 新生代GC
    新生代通常存活时间较短,因此基于复制算法来进行回收,所谓复制算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中
    新生代满了后,会把对象转移到旧生代,然后清空继续装载,当旧生代也满了后,就会报outofmemory的异常
  2. 老年代GC
    老年代对象存活的时间比较长,比较稳定。因此采用标记(Mark)算法来进行回收,所谓标记就是扫描出存活的对象,然后再进行回收未被标记的对象,回收后对用空出的空间要么进行合并,要么标记出来便于下次进行分配,总之就是要减少内存碎片带来的效率损耗
posted @ 2020-11-12 17:36  猫熊小才天  阅读(90)  评论(0编辑  收藏  举报