JVM内存的分配和回收

内存的分配:

1)指针碰撞(bump the pointer):适用于内存整齐的情况,已使用的在一边,未使用的在一边。

新生代对象的内存分配

2)空闲列表(free list):内存中已分配和未分配的内存互相交错,用链表记录空闲内存块。

老年代对象的内存分配

多线程分配可能导致分配不安全,有以下策略:

1)CAS分配(失败-重试策略)

2)(本地化)TLAB:Thread Local Allacation Buffer:本地线程分配缓冲区,为线程预先分配一块内存。

哪些内存需要回收?

程序计数器,JVM方法栈,本地方法栈所占用的内存的回收都有确定性,所以内存回收主要指的是堆和元空间(JDK8以前是方法区)

什么样的对象需要回收?

死掉的对象。判断对象的生死一般有两种算法:

1)引用计数算法:缺点是不能解决循环引用的问题

2)可达性算法:根对象所不能到达的对象。常见的根对象有:栈帧中引用的对象,常量等。

对象的引用

1)强引用:永远不会被回收

2)软引用:内存紧张的时候会被回收

3)弱引用:GC时一定会被回收

4)虚引用:无法通过虚引用得到一个实例

废弃的常量和类也需要回收。

对象的内存分配需要一块连续内存。

对象优先在堆中新生代中的Eden区分配,如果空间不够,将触发Minor GC。

分配担保:如果老年代的连续空间大于新生代对象总和或历次晋升平均值,那么将触发Minor GC,否则触发Full GC。一般Full GC比Minor GC慢10倍以上。

长期存活的新生代对象会进入老年代

年龄计数器:每经历一次MinorGC,计数器加1,到了一定年龄会晋升到老年代。

动态年龄:如果某年龄的对象大于新生代一般,那么大于等于这个年龄的对象都会晋升到老年代。

如果对象大于某阈值(-XX:PretenureSizeThreshold),那么直接在老年代分配空间。


JVM内存的分配和回收_第1张图片

新生代和老年代是什么关系?

老年代为新生代提供分配担保。

新生代中存活的对象将存放在老年代中的,但这带来一个问题:老年代是否有足够的空间存放晋升而来的对象呢?

当新生代不足以为新对象分配空间时,触发Minor GC,在此之前JVM会检查老年代最大可用连续空间是否大于新生代所有对象 或者 历次晋升到老年代对象的平均大小,如果成立则进行Minor GC,否则将进行Full GC。

你可能感兴趣的:(JVM内存的分配和回收)