zoukankan      html  css  js  c++  java
  • jvm中的堆

    一.Java堆从GC的角度去看,可以分为三个区域,分为是新生代,老年代,永久代(是方法区的实现,但是物理逻辑是和堆在一起的)

      其中新生代占1/3的堆空间,老年代占2/3的堆空间,永久代占得很少,就不进行划分了,他也占了,但是很少很少,新生代占的1/3又分为Eden区(占比8/10),ServivorFrom区(占比1/10),ServivorTo区(占比1/10),大概的占比图如下

                              

      1.gc
        1)如果进行了一次gc后还存活,age+1,然后进入新生代中的s0区
        2)GC会根据区域的剩余内存进行判断是否进行清理
        3)如果age等于15时,进入老年代,长期存活的对象进入老年代
        4)动态年龄判断:如果s0中有一部份的对象的内存大于它的50%,则将年龄大的放进老年代

      2.使用gcroot判断对象是否可达,来判断对象是否可被回收(是否为垃圾),哪些可以被作为gcroot呢:

        1、栈(栈帧中的本地变量表)中对象的引用。

        2、方法区中的静态成员。

        3、方法区中的常量引用的对象(全局变量)。

        4、本地方法栈中JNI(一般说的Native方法)引用的对象。

    1.新生代

      我们新创建的对象(除了大对象,大对象是直接放进了老年代)都是放在新生代中的,由于JVM会频繁的创建对象,所以就会频繁的触发GC,新生代时的GC叫做MinorGC

    新生代中分为了三个区域,分别时Eden、ServivorTo、ServivorFrom(这两空间交替变成ServivorTo和ServivorFrom的)

      Eden:我们新创建的对象首先就会放入到Eden区,当Eden区的内存不足时会触发MinorGC

      ServivorTo:存放上一次MinorGC的幸存者,也是下一次的ServivorFrom区

      ServivorFrom:存放的是上一次MinorGC的幸存者,在上一次中他是ServivorTo区,他在这一次中充当被扫描者的角色

    其实从上面的几个介绍来看,可能就只能理解Ened是干嘛的,如果了解了MinorGC的流程就会很清楚了

    MinorGC(使用的复制算法):将空间划分为两份,一个预留,一个实际,在进行GC时,将预留的开启,将没被删除的放进预留的内存块,将实际的转换为预留的

    MinorGCC的具体过程是采用复制算法实现的,具体步骤如下:

      1、首先会把Eden区与ServivorFrom区中存活的对象复制到ServivorTo区中去。这里会将达到了老年代的标准的对象复制到老年代区去,然后整体对象的标准年龄+1(15为老年代的标准),如果ServivorTo的内存不足的情况,存活的对象就直接全部复制到老年代

      2、清空Eden区与ServivorFrom区

      3、将ServivorTo区与ServivorFrom区互换,原本的ServivorTo区成为了下一次ServivorFrom区,然后下一次他里面的对象又要被复制到下一次的ServivorTo区中区

    2.老年代

      老年代主要存放的就是长生命周期的对象和大对象,不会频繁出发GC了,老年代的GC叫做MajorGC,在进行老年代GC之前,他会调用新生代的GC一次,然后将那些要存放到老年代的对象都复制过来,如果在新生代GC后,老年代的空间不足,那么就会触发MajorGC

      老年的GC采用的是标记清除法,标记清除算法:在GC的过程中,将要删除的标记删除,但会产生内存碎片

      他会去扫描所有的对象并且标记存活的对象,然后回收掉所有未标记的对象。MajGC因为要扫描所有的对象,所以耗时会较长,而且标记清除法也容易产生内存碎片,老年代内存空间不足时,会触发OOM

    3.永久代

    永久代主要保存的是Class和元数据信息,Class在类加载时被放入永久代,永久代不会触发GC,因为他不会GC,所以他的内存会随着加载Class文件的增加而增加,加载的Class文件过多时就会OOM,比如Tomcat引用的jar文件过多时就会导致JVM内存不足而无法启动

    在1.8之前,永久代是用的JVM虚拟机的内存,所以他的实际可用内存就受到了JVM内存的限制,1.8之后用的是操作系统的内存

  • 相关阅读:
    CISCO DHCP全攻略详解
    CentOS配置远程日志服务器
    CentOS下的日志切割
    CentOS日志的简单介绍
    H3C Telnet 配置
    CentOS7图形界面与命令行界面切换
    思科4506E做ehterchannel故障排查
    EtherChannel Cisco 端口聚合详解
    算法练习2之单链表求和
    Retrofit2的GsonConverterFactory.create()和RxJava2CallAdapterFactory.create()的实现过程以及执行过程
  • 原文地址:https://www.cnblogs.com/nyhhd/p/12620065.html
Copyright © 2011-2022 走看看