程序员

JVM 内存管理

2019-04-07  本文已影响0人  二毛_220d

内存管理=内存分配+内存回收

内存分配

WechatIMG3.jpeg

JMM指Java内存管理
线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存,又称作TLAB线程本地缓冲区,中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。

WechatIMG1.jpeg

虚拟机栈

特点如上图。
局部变量表存放了各种基本数据类型,对象引用类型,(“对象引用”可能是一个对象起始地址的引用指针,也可能是一个指向代表对象的句柄,不同的JVM实现不同),和return Address类型
StackOverflow : 栈深度超出允许范围
OutOfMemory: 当虚拟机栈在动态扩展时,无法申请到足够的内存则抛出

WechatIMG2.jpeg

JVM规范中规定的是:所有对象实例及数组都要在堆上分配,但随着编译器发展,也出现了栈上分配等优化技术

没有在堆上完成对象的内存分配并且也无法扩展堆大小时,将抛出OutOfMemoryError

方法区

运行时常量池

内存溢出

内存回收

垃圾回收 — 如何判断对象已死

  1. 引用计数器
  2. 可达性分析
    2.1. 栈帧中引用的对象
    2.2. 方法区中静态属性引用的对象
    2.3. 方法区中常量引用的对象
    2.4. JNI引用的对象
    引用计数很难解决循环引用问题
    可达性分析通过从GC-Root,可能有多个,出发进行搜索,凡是没有在任何路径上的对象,就可以回收了

回收算法

  1. 标记-清除
    1.1. Stop The World
    1.2. 会产生大量碎片
  2. 复制
  3. 标记-整理
    3.1. 无需额外空间
  4. 分代收集
    4.1. 针对各年代的特点,采用不同算法。

标记就是通过可达性分析算法,为所有有引用的对象都打上标记,在标记和清除阶段,都需要将整个程序暂停,也就是stop-the-world。
复制算法,如果不想浪费50%的空间,就必须有额外空间做担保,例如老年代给新生代担保,那么由于没有再额外的空间给老年代担保了,所以老年代就不能采用复制算法。
标记-整理,又称作标记压缩,适合于老年代。

垃圾收集器

Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old
CMS 、G1
CMS是知道Java7为止默认的server模式的垃圾收集器
G1在Java7引入,在Java8成为推荐

上一篇 下一篇

猜你喜欢

热点阅读