jvm之内存分配

jvm内存:

        分为栈,堆,方法区。

        堆内存是所有线程共享的内存区域:存储了所有的对象实例,数组对象,静态对象。为了便于jvm垃圾回收,将堆内存分为新生代和年老代。

        新生代:分配对象首先分配在新生代。

        新生代对象的特点:生命周期短,存活时间低。

        新生代垃圾回收:minor gc  发生频繁,采用复制算法来进行垃圾回收。

        复制算法:新生代内存区域被分为两块:在分配对象的时候首先在一块区域分配,当出现gc时,会将存活的的对象直接复制到另外一块内存区域,之后清理上一块内存区域。

        反映到jvm上就是:新生代分为一个eden区域,两个survior区域,默认比例是8:1,分配对象优先分配在eden区,当内存不足以分配新对象时,触发minor gc,会将eden中存活的对象直接转移到survior中的to区,survior中的from区中对象年龄达到年老代阈值时,转移到年老代,否则转移到to区,这样from中内存就没有在使用,from和to互换角色,承担对方的职责。

        年老代:存活时间长的对象。

        特点:对象一般较大,且存活时间长。

        垃圾回收:major gc 至少伴随着一次minor gc 所以也叫做 full gc,年老代采用标记清除,或者是标记整理算法。

        标记清除:将需要回收的对象标记,之后清除,存在效率问题,且存在大量的空间碎片,当年老代控件不足时,提前触发full gc。

        标记整理:弥补了上面的缺点,会将内存空间整理成连续的空间。

(1)对象优先分配在eden区

(2)大对象直接分配在年老区 (大对象指数组这类对象)

(3)长期存活的对象直接进入年老代

(4)若survior中存活的对象的大小超过survior的一半,那么内存占用大于等于该内存的对象直接进入年老代

(5)空间分配担保:若eden区无法分配对象,请求在年老代直接分配对象,但存在风险,若年老代空间不足,会提前触发full gc。

    尽量避免full gc 因为full gc 伴随着的stop the word 即暂停所有的线程,且full gc时间较长,容易导致长时间服务器没有响应。

猜你喜欢

转载自blog.csdn.net/qq_32182461/article/details/80320012