垃圾回收GC

/**
 * 什么是垃圾:内存中已经不再被使用的空间。
 * 如何判断对象是否被GC:
 * 1 引用计数器值为0:不用,不能解决对象之间互相循环引用问题。
 * 2 枚举根节点做可达性分析(根搜索路径):GC roots(tracing GC)根集合:一组必须活跃的引用。给定一个集合的引用作为根出发,通过引用关系遍历对象图,能被遍历到的(可达的)对象就被判定为存活,没有遍历到的判定为死亡。
 *   适用于复制、标记清除、标记压缩。
 *   java中可作为GC Roots的对象:
 *      1虚拟机栈(栈帧中的局部变量区,也叫局部变量表,)中引用的对象;
 *      2方法区中的类静态属性引用的对象;
 *      3方法区中常量引用对象。
 *      4本地方法栈中JNI(Native方法)引用的对象。
 *
 * 垃圾回收方法:
 * 1 引用计数法(已经不采用)  缺点:每次对象赋值时都要维护引用计数器,且计数器根深也有一定的消耗;2难处理循环引用。
 * 2 复制:
 *      1 eden和survivorFrom复制到survivorTo,年龄+1;
 *          eden区满,出发第一次GC,把活着的对象copy到survivorFrom区,当eden区满再次触发GC,扫描eden和survivorFrom,这两个区进行垃圾回收,
 *              任然存活的对象copy到survivorTo区(如果年龄到了老年标准,则赋值到老年区),同时把这些对象的年龄+1
 *      2 清空eden和survivorFrom
 *      清空eden和survivorFrom复制之后有交换,谁空谁是to。
 *      3 survivorFrom和survivorTo互换。
 *      原survivorFrom成为下一次的survivorTo,部分对象会在两个区间复制多次,如果交换15次(由JVM参数MaxTenuringThreshold配置,默认15)仍存活,则存入老年代
 * 3 标记清除(mark-sweep):先标记出,在统一回收
 * 4 标记压缩(整理)(mark-compact):(1)标记清除 (2)压缩:  获得连续空闲内存区域。
 *
 * 垃圾收集器类型(垃圾回收方式 ):
 * 1serial(串行垃圾回收器):为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有用户线程,不适合服务器。 程序-gc-程序 -XX:+UseSerialGC
 * 2parallel(并行垃圾回收器):多个垃圾收集线程并行运行,用户线程暂停,适用于科学计算/大数据处理等弱交互场景 -XX:+UseParallelGC(java8默认)
 * 3CMS(并发垃圾回收器):(并发标记清除)用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程。互联网公司多用,适用于对相应时间有要求的场景。会出现内存碎片
 * 4G1(G1适用于堆内存很大的情况):将堆内存分割成不同的区域,然后并发的对他们进行回收。
 *
 *
 *
 * 串行和并行:单核cpu下并行可能更慢
 * STW(stop-the-world)和并发:STW暂停整个应用,时间可能会很长;并发更为复杂,GC可能会抢占应用的CPU
 *
 *
 *
 *
 * 如何查看默认的垃圾收集器:
 * Idea-terminal:java -XX:+PrintCommandLineFlags -version
 *
 *
 *
 * java的gc回收的类型主要有哪几种?
 * UseSerialGC、UseParallelGC、UseConcMarkSweepGC、UseParNewGC(young区的串行GC)、UseParallelOldGC(老年区的并行GC),UseG1GC、UseSerialOldGC(已废弃)
 *
 *
 *
 *设置程序GC:
 * IDEA: RUN--EDIT CONFIGURATIONS--APPLICATION:HelloGC--CONFIGURATIONS:VM OPTIONS 设置为-XX:+UseSerialGC,应用。
 * 查看GC:
 * 1运行HelloGC
 * 2teiminal:
 *      1 jps -l :获得线程编号;
 *      2 jinfo -flag UseSerialGC 线程编号 :显示-XX:+UseSerialGC 如果为+UseSerialGC,则启用,如果为-UseSerialGC,则未启用。
 *
 *
 *
 * 新生代:
 * 1串行GC(serial/serial copying):单线程 STW状态 适用于单CPU单线程。 用在java虚拟机Client模式默认的新生代垃圾收集器。
 *   JVM参数:-XX:+UseSerialGC;开启后使用serial(young)+serial old(old)收集器组合;新生代使用复制算法,老年代使用标记清除
 * 2并行GC(ParNew):多线程 STW状态 用在java虚拟机Server模式默认的新生代垃圾收集器。
 *   JVM参数:-XX:+UseParNewGC;开启后只影响新生代,不影响老年代;ParNew(young)+serial old(old)收集器组合(这种组合java8y已不再推荐);新生代使用复制算法,老年代使用标记清除
 *   -XX:ParallelGCThreads 限制线程数量,默认开启和CPU数目相同的线程数
 * 3并行回收GC(Parallel/Parallel scavenge):类似ParNew,新生代,复制算法,并行多线程,俗称吞吐量有限的垃圾收集器。串行收集器在新生代和老年代的并行化。
 *   与ParNew的区别:可控的吞吐量。高吞吐量意味着高效利用CPU的时间,它多用于在后台运算而不需要太多交互的任务;自适应调节策略:虚拟机h会根据当前系统的运算情况收集性能监控信息,
 *   动态调整以提供最合适的停顿时间(-XX:MaxGCPauseMills)或最大吞吐量.
 *   JVM参数:-XX:+UseParallelGC 或-XX:+UseParallelOldGC(可相互激活);新生代使用复制算法,老年代使用标记整理
 *-XX:ParallelGCThreads=数字N 表示启用N个GC线程;cpu>8 N=5/8;cpu<8 N=cpu个数
 *
 *
 *老年代:
 * 1串行GC(serialOld/serial msc):单线程 STW状态 适用于单CPU单线程。 用在java虚拟机Client模式默认的新生代垃圾收集器。
 *   JVM参数:-XX:+UseSerialGC;开启后使用serial(young)+serial old(old)收集器组合;新生代使用复制算法,老年代使用标记清除
 * 2并行GC(Parallel old/Parallel msc):多线程 STW状态 用在java虚拟机Server模式默认的新生代垃圾收集器。
 *   JVM参数:-XX:+UseParNewGC;开启后只影响新生代,不影响老年代;ParNew(young)+serial old(old)收集器组合(这种组合java8y已不再推荐);新生代使用复制算法,老年代使用标记清除
 *   -XX:ParallelGCThreads 限制线程数量,默认开启和CPU数目相同的线程数
 * 3并发标记清除GC(CMS):类似ParNew,新生代,复制算法,并行多线程,俗称吞吐量有限的垃圾收集器。串行收集器在新生代和老年代的并行化。
 *   与ParNew的区别:可控的吞吐量。高吞吐量意味着高效利用CPU的时间,它多用于在后台运算而不需要太多交互的任务;自适应调节策略:虚拟机h会根据当前系统的运算情况收集性能监控信息,
 *   动态调整以提供最合适的停顿时间(-XX:MaxGCPauseMills)或最大吞吐量.
 *   JVM参数:-XX:+UseParallelGC 或-XX:+UseParallelOldGC(可相互激活);新生代使用复制算法,老年代使用标记整理
 *-XX:ParallelGCThreads=数字N 表示启用N个GC线程;cpu>8 N=5/8;cpu<8 N=cpu个数
 *
 *
 *ParallelOldGC:是Parallel Scavenge的老年代版本,使用多线程标记-整理算法,在jdk1.6之后开始提供。jdk1.6之前Parallel Scavenge使用的是serialOld,
 *               jdk1.8之后用Parallel Scavenge+ParallelOld;
 *               JVM参数:-XX:+UseParallelOldGC 使用ParallelOldGC,新生代自动激活ParallelGC
 *
 *
 *CMS收集器:以获得最短回收停顿时间为目标的收集器。适用互联网站或者B/S系统服务器上,重视服务器的响应速度,希望系统停顿时间短。适合堆内存大、CPU核数多的服务器端应用,也是G1之前大型应用的首选收集器。
 *          要求低停顿,并发指与用户线程一起。
 *          JVM参数:-XX:+UseConcMarkSweepGC,开启后系统自动将-XX:UseParNewGC打开,使用ParNew(young)+CMS(old) +SerialOld收集器集合,SerialOld作为CMS出错后的备用收集器。
 *          4步:初始标记(停)、并发标记(不停)、重新标记(停)、并发清除(不停)
 *          由于并发,CMS会增加堆内存的占用,cms必须在老年代内存用尽之前完成回收,否则cms回收失败,触发担保机制-串行老年代收集器静将STW方式进行一次性GC,造成长时间停顿。
 *          优点:并发低停顿;缺点:并发CPU压力大;标记清除导致大量碎片;
 *          标记清除算法无法整理空间碎片,老年代空间会随着应用时间增长被逐步耗尽,最后通过担保机制对堆内存压缩。CMS提供参数-XX:+CMSFullGCsBeforeCompaction(默认0,即每次都进行内存整理)来指
 *          定多次CMS收集之后,进行一次压缩的Full GC.
 *
 *
 *新生代和老年代GC的特点:
 *  1年轻代和老年代是各自对立且连续的内存块;
 *  2年轻代使用单eden+s0+s1进行复制算法
 *  3老年代收集必须扫描整个老年代区域
 *  4设计原则:少而快的执行GC
 *
 *
 *G1:Garbage-First,面向服务端应用的收集器,多处理器和大容量内存,高吞吐量且满足垃圾收集暂停时间要求。
 *1并发执行 2整理空闲空间更快 3需要更多的时间来预测GC停顿时间 4不希望牺牲大量的吞吐性能 5不需要跟打的java heap
 *设计目标:取代CMS. 与CMS比优点:整理内存碎碎片;STW更可控,用户可指定期望停顿时间。jdk1.9之后默认G1,减少停顿时间,提高服务器性能。
 * 主要改变:eden survivor Tenured等内存区域不再是连续,变成了大小一样的region(1-32M),每个region可能属于eden survivor tenured。
 * 特点:
 *      1利用多核,大内存优势,缩短STW。
 *      2整体上标记整理,局部复制算法,不产生内存碎片。
 *      3不在区分young和old,划分成region
 *      4内存整个在一起,但自身小范围内区分young和old,但不再是物理隔离,而是一部分region的剂盒且region不需要时连续的,依然需要不同的方式处理不同区域
 *      5依然是分代收集器,但整个内存不存在物理上的young和old,也没有完全独立的survivor堆做复制准备。G1只有逻辑上的分代,每个region可在不同代之间切换。
 *底层原理:
 *      1 region区域化垃圾收集器:化整为零,避免全内存扫描,只需要按照区域扫描。核心思想:真个堆内存划分大小一样的区域,jvm启动时自动设置region大小。堆使用中,不要求region物理上连续,逻辑上连续即可。
 *        每个region也不会固定为某代 ,可以根据需要在young和old之间来回切换。启动时-XX:G1HeapRegionSize=n(1-32MB,不许是2的幂次方),默认整堆为2048个region。
 *        最大支持内存64G
 *        G1算法推到region,仍属于分代收集器。region中部分属于young,采用复制算法,暂停所有应用线程,将存活对象copy到old或者survivor空间。region中部分属于old,将对象从一个region复制到另一个region,
 *        完成清理,即完成堆的压缩,不会有内存碎片问题存在。
 *        G1中的巨型对象放在Humongousq区,如果一个Humongousq装不下,会用连续的H分区来存储。有时为了找到来纳许的H区,不得不启动Full GC.
 *      2 回收步骤:
 *        YoungGC:针对eden区进行收集,eden满触发,主要是小区域收集+形成连续的内存块,避免内存碎片。
 *              eden区数据移动到survivor区,如果survivor区空间不够,eden区部分直接晋升到old。
 *              survivor区数移动到survivor区,部分晋升到old。
 *              最后eden区收拾干净,GC结束,用户的应用线程继续执行。
 *              1初始标记stw:只标记GC Root能直接关联的对象
 *              2并发标记:进行GC Roots Trancing的过程
 *              3最终标记stw:修正并发标记期间因程序运行导致的部分发生变化的对象
 *              4筛选回收stw:根据时间来进行价值最大化的回收
 *JVM参数:-XX:+UseG1GC -Xms32g -XX:MaxGCPauseMillis=100   开始G1 设置最大内存 设置最大停顿时间单位毫秒,jvm尽可能停顿小于这个时间。
 *
 *
 *
 *JVMGC + SpringBoot微服务性能调优:
 * 1 内部发布:idea:RUN--EDIT CONFIGURATIONS--APPLICATION:HelloGC--CONFIGURATIONS:VM OPTIONS 设置为-XX:+UseSerialGC,应用。
 *             查看GC:
 *                  1运行HelloGC
 *                  2teiminal:
 *                      1 jps -l :获得线程编号;
 *                      2 jinfo -flag UseSerialGC 线程编号 :显示-XX:+UseSerialGC 如果为+UseSerialGC,则启用,如果为-UseSerialGC,则未启用。
 * 2 外部发布:1 cdm至war包所在目录  2输入 java -server -Xms1024m -Xmx1024m -XX:UseG1GC -jar war包名.war
 *           查看:cmd到当前用户下 1 jps -l  2 jinfo -flags 进程号
 *
 *
 *
 *
 *
 *
 *
 *
 */
public class HelloGC {
    public static void main(String[] args) {
        System.out.println("************HelloGC");
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值