zoukankan      html  css  js  c++  java
  • GC垃圾回收

    一、垃圾

    在c或c++中垃圾是要手动进行回收的

    Java:new对象申请内存

          自动回收内存,若手动释放内存,容易出现两种类型问题:

        1、忘记回收,导致内存溢出

        2、多次回收

    二、什么是垃圾

    1、如果一个对象没有任何引用指向他

    2、存在多个对象,互相之间引用,没有其他对象指向这个循环引用的对象(多个)

    三、如何定位垃圾

    1、引用计数法:一个对象有几个引用,这个对象中的计数器为相应的数,当计数器为0时,为垃圾(不能解决循环引用的问题)

    但是,当三个对象循环引用,每个对象的计数器都为1,此时没有对象引用该整体时,会发生内存泄漏

     2、根可达算法:程序会找到一些根对象,与根对象有关联的都不是垃圾,其余都是垃圾

     四、垃圾回收算法

    1、标记清除:找到垃圾后清除,相应区域标记为非垃圾区域

    存在问题:位置不连续、产生碎片

     黑色为垃圾,绿色为未使用

    2、拷贝:将内存区域非为两半,在上半区找到正在使用的内存,拷贝到下半区。拷贝完成后将上半区清空,标记为未使用区域,需要内存时往下半区分配

    存在问题:浪费空间,需要准备两份。项目中需要5G,你要准备10G内存

    3、标记压缩:从头开始按照顺序,将存活对象拷贝到可回收区域,形成连续空间

    好处:没有碎片,内存连续。但是效率偏低

    效率偏低原因:若单线程操作,效率本身就低

           若多线程操作,需要线程同步

     五、JVM内存分代模型

    1、部分垃圾回收器使用的模型

    2、新生代+老年代+永久代(1.7)/元数据区(1.8)

      永久代、元数据都是装Class对象中

      永久代必须指定大小限制,元数据区可以设置也可以不设置

    3、堆内存逻辑分区

    新生代=伊甸+2个survivor区 

      ①YGC回收之后,大多数内存会被回收,存活的对象进入S0,伊甸园区清空

      ②伊甸+S0中存活的对象拷贝到S1中,其余两个区域清空

      ③再次YGC,伊甸+S1中存活对象放到S0中

      ④当对象年龄足够大或S区装不下后,放到老年代中

    老年代满之后会触发FGC(Full GC)

    4、调优目标:尽量减少FGC

     默认新生代:老年代=1:3

    新生代中伊甸:survivor:survivor = 8:1:1

    六、常见的垃圾回收器

     Serial(年轻代,串行回收,单线程):从左到右,空间满了,触发GC,所有程序线程停止,垃圾回收线程进行垃圾回收,回收后程序继续运行

     蓝色的线表示程序正常运行

    Paraller Scavenge(年轻代,并行回收)

     ParNew(年轻代):配合CMS的并行回收

    SerialOld:将Serial放到old区

    ParallelOld:将Parallel放到old区

    CMS(老年代):在进行垃圾回收的时候程序也可以运行,效率较高,降低STW的时间(200ms)

    G1(10ms)

    ZGC(1ms)

    作者:http://cnblogs.com/lyc-code/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权力。

  • 相关阅读:
    Java内存模型
    BigDecimal踩过的大坑
    Java开发小技巧
    多线程同步辅助工具类
    ReentrantLock中的公平锁与非公平锁
    ReentrantLock与synchronized的区别
    推荐一个Java设计模式写的很好的博客
    线程池ThreadPoolExecutor工作原理
    支付系统架构设计转载
    linux 部署脚本
  • 原文地址:https://www.cnblogs.com/lyc-code/p/14748119.html
Copyright © 2011-2022 走看看