美文网首页
JVM内存的分配和回收

JVM内存的分配和回收

作者: packet | 来源:发表于2018-07-20 19:41 被阅读0次

    内存的分配:

    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),那么直接在老年代分配空间。



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

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

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

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

    相关文章

      网友评论

          本文标题:JVM内存的分配和回收

          本文链接:https://www.haomeiwen.com/subject/ennqmftx.html