• JVM年轻代,老年代,永久代详解


    前言

    最近被问到了这个问题,解释的不是很清晰,有一些概念略微模糊,在此进行整理和记录,分享给大家。本篇文章主要讲解内存区域的年轻代,老年代和永久代,略微提及一些垃圾回收算法,下面是正文。

    堆整体

    堆主要用于存放各种类的实例对象和数组。在java中被分为两个区域:年轻代和老年代。在java中还有一个永久代的意思,这里最后会单独说明。

    年轻代和老年代的划分是为了更好的内存分派及回收。提高效率。
    堆是垃圾回收机制的重点区域。我们知道垃圾回收机制有三种,minor gc,major gc 和full gc。针对于堆的就是前两种。年轻代的叫 minor gc,老年代的叫major gc。

    年轻代

    年轻代用来存放新近创建的对象,尺寸随堆大小的增加和减少而相应的变化,默认值是保持为堆的1/15。
    年轻代的大小可以通过-xmn设置固定大小,也可以通过-xx:newratio设置年轻代和年老代的比例。
    年轻代中存在的对象是死亡非常快的。存在朝生夕死的情况。
    所以为了提高年轻代的垃圾回收效率,又将年轻代划分为三个区域,一个eden和两个sunrvivor from。

    eden和survivor默认比例是8:1:1,进行垃圾回收采用的是分代复制算法。每次新生代的使用,会是eden区和一块survivor区。当我们进行垃圾回收的时候,清除正在使用的区域,将其中的存货对象,放入到另一个survivor区域,并进行整理,保证空间的连续。如果对象长时间存活,则将对象移动到老年区。存活下来的对象,他的年龄会增长1。当对象的年龄一次次存活,一次次增长,到达15的时候,这些对象就会移步到老年代。在年轻代执行gc的时候,如果老年代的连续空间小于新生代对象的总大小,就会触发一次full gc。是为了给新生代做担保,保证新生代的老年对象可以顺利的进入到老年代的内存区。

    老年代

    老年代中存放的对象是存活了很久的,年龄大于15的对象。在老年代触发的gc叫major gc也叫full gc。full gc会包含年轻代的gc。但老年代只要执行gc就一定是full gc。
    full gc采用的是标记-清除算法。会产生内存碎片。在执行full gc的情况下,会阻塞程序的正常运行。老年代的gc比年轻代的gc效率上慢10倍以上。对效率有很大的影响。

    永久代

    永久代是hotspot虚拟机,也就是我们使用的java虚拟机的特有的概念,他不属于堆内存,是方法区的一种实现,各大厂商对方法区有各自的实现。永久代存放jvm运行时,需要的类,包含java库的类和方法,在触发full gc的情况下,永久代也会被进行垃圾回收。永久代的内存溢出也就是 pergen space。

    元空间

    元空间是metaspace,在jdk1.8的时候,jvm移除了永久代的概念,元空间也是对java虚拟机的方法区的一种实现。元空间与永久代最大的区别在于,元空间不在虚拟机中,使用本地内存。通过配置如下参数可以更改元空间的大小。
    -XX:MetaspaceSize:初始空间的大小。达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。
    -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。
    永久代的回收会随着full gc进行移动,消耗性能。每种类型的垃圾回收都需要特殊处理元数据。将元数据剥离出来,简化了垃圾收集,提高了效率。

  • 相关阅读:
    Vijos P1448 校门外的树【多解,线段树,树状数组,括号序列法+暴力优化】
    Vijos P1785 同学排序【模拟】
    Vijos P1784 数字统计【模拟】
    Vijos P1497 立体图【模拟】
    将你的wordpress博客添加到百度个性首页
    改变wordpress图片上传后的压缩质量
    优化dedecms设置文章url自定义规则
    dedecms首页调用随机文章全自动时时更新
    怎样在wordpress后台显示日志 ID
    sql批量修改wordpress文章发布时间
  • 原文地址:https://www.cnblogs.com/jichi/p/12580906.html
Copyright © 2020-2023  润新知