首页 > 其他分享 >JVM系统优化实践(5):什么时候GC以及有哪些GC

JVM系统优化实践(5):什么时候GC以及有哪些GC

时间:2023-02-27 22:02:22浏览次数:55  
标签:系统优化 Eden Survivor 对象 GC 引用 JVM new

您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~

 


 

 

既然程序运行会产生大量的废弃物,也就是「垃圾」,那总不能一直堆着不管吧。现在就来粗浅地谈谈Java里面什么时候会触发GC以及有哪些GC。

通过之前的电商支付系统,可以知道系统运行创建的对象都是优先分配在JVM的年轻代中的,年轻代里面的对象越来越多快满的时候就会触发垃圾回收机制。

这就涉及到一个「可达性分析法」,也就是判定哪些对象可以被回收,哪些不能被回收:只要某个对象被局部变量引用,就说明该对象有一个GC Roots,此时就不能被回收了。

所谓GC Roots,在一般情况下指的是方法的局部变量和静态变量。只要对象被方法的局部变量、静态变量给引用了,它就不能被回收了,至少不能被马上回收。

Java对象有几种不同的引用类型:

1、强引用:一个变量显式地引用一个对象;

2、软引用:对一个匿名内部类或者对引用的引用,例如:

// 强引用

String str = new String(“abc”);

// 软引用

SoftReference<String> softref = new SoftReference<String>(str);

// 也是软引用

SoftReference<String> softref = new SoftReference<String>(new String(“abc”));

3、弱引用:只具有弱引用的对象拥有更短暂的生命周期,例如:

// 弱引用

WeakReference<String> weakref = new WeakReference<String>(new String(“abc”));

str = null;

4、虚引用:顾名思义,就是形同虚设,实际中很少使用,可以不管。

 

再来看看有哪些GC方法。

年轻代的内存被分为两部分,其中一块创建对象实例,供栈中的局部变量引用。当空间不足时,就可能触发年轻代的垃圾回收:

 

 

 

由于一瞬间回收掉大量垃圾对象时,可能会造成大量的空白内存区域,大小不一,非常凌乱,造成大量的内存浪费,因此不能直接清除垃圾对象而保留存活对象。所以合理的做法就是复制(复制算法):

1、先保留存活对象;

2、再将存活对象转移(复制)到另一块空白内存中;

3、最后将原区域整体回收;

4、两块区域循环往复着使用。

 

 

 

这就是GC当中最最简单、最最基础的复制算法。

它的缺点是:空间使用效率只有50%。从图上可以明显看得出来,比较浪费,空间越大越浪费。

优化:将年轻代划分为三块:

1、1个Eden区:占80%年轻代空间;

2、2个Survivor区:S0、S1各占10%年轻代空间;

平常情况下可以使用的,就是Eden区和其中一块Survivor区(比如S0):

 

 

 

如果Eden区快满了,就会触发Minor GC:

1、Minor GC时,Eden中的存活对象会一次性转移到另一块空闲的Survivor区中区(比如S1);

2、Eden区被清空,然后被再次分配新对象;

3、如果Eden再满,再次触发Minor GC;

4、将Eden和S1中的存活对象转移到S0中去;

5、如此循环往复。

 

对象不可能永远年轻,总会慢慢变老。自然世界用光阴让人两鬓斑白,JVM则默默记住对象的「劫数」,并以此决定它的生死:

对象每在年轻代“躲过”一次GC而被转移到另一个Survivor时,对象“年龄”就会增加“一岁”(被标记一次),默认是被标记15次之后,就会被转移到老年代,可通过-XX:MaxTenuringThreshold参数设置。

 

 

 

当然计算机世界还有自己的规则——除了被标记,还有另一个规则可让对象进入老年代——如果当前Survivor区中,年龄相同的一批对象总大小 ≥ Survivor × 50%,那么这批对象及比它们年龄更大的对象,就都直接进入老年代。例如:如果年龄1 + 年龄2 + 年龄3 ≥ Survivor × 50%,那么大于等于年龄3的所有对象都进入老年代。

 

 

 

计算机的规则只有工程师可以干预:通过设置参数XX:PretenureSizeThreshold的值,可以直接将大对象放到老年代,根本就不经过年轻代。

工程师就是计算机的上帝!

 


 

 

感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~

标签:系统优化,Eden,Survivor,对象,GC,引用,JVM,new
From: https://www.cnblogs.com/xiangwang1111/p/17162090.html

相关文章

  • gcc编译过程
    编译过程:预处理、编译、汇编、链接预处理:包括宏替换、删除注释、头文件包含、条件编译(这个阶段不会报语法错误)gcc-Ehello.c-ohello.i编译:将预处理......
  • springcloud集成nacos(详细)
    一、什么是nacos官方:一个更易于构建云原生应用的动态服务发现、服务配置、和服务管理平台理解:注册中心(如:服务地址注册进去根据名称调用)、配置中心(如:每个服务yaml中的配置......
  • gcc 内联汇编简介
    啊 啊 在内联汇编中,标识寄存器的一个%变成了两个%啊 如图是内联汇编的模板assemblertemplate是汇编代码outputoperandsTODOinputoperandsTODOclobb......
  • 谈JVM xmx, xms等内存相关参数合理性设置
    作者:京东零售刘乐说到JVM垃圾回收算法的两个优化标的:吞吐量和停顿时长,并提到这两个优化目标是有冲突的。那么有没有可能提高吞吐量而不影响停顿时长,甚至缩短停顿时长呢?......
  • C++快速求解最大公因数 | gcd库函数
    1.介绍gcd全称:greatestcommondivisor使用__gcd(intx1,intx2)函数可以高效、迅速得到x1,x2两个数的最大公因数。省去手写底层代码,专注代码逻辑的研究 2.注......
  • linux之gcc
    #################usr是unixsystemresource缩写,不是user缩写;  /lib,/usr/lib,/usr/local/lib的区别:/lib是内核级的;/usr/lib是系统级的;/usr/local/lib是用户级的......
  • JVM系统优化实践(4):以支付系统为例
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~   前面说过,JVM会将堆内存划分为年轻代、老年代两个区域。年轻代会将创建和使用完之后马上就要回收的对象放在里面,......
  • JVM系统优化实践(4):以支付系统为例
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~前面说过,JVM会将堆内存划分为年轻代、老年代两个区域。年轻代会将创建和使用完之后马上就要回收的对象放在里面,而老年代则......
  • SpringCloud 源码学习笔记2——Feign声明式http客户端源码分析
    系列文章目录和关于我一丶Feign是什么Feign是一种声明式、模板化的HTTP客户端。在SpringCloud中使用Feign,可以做到使用HTTP请求访问远程服务,就像调用本地方法一一样的......
  • 深入理解JVM学习笔记
    Java虚拟机内存区域:[2.2]运行时数据区域:1.程序计数器2.Java虚拟机栈3.本地方法栈4.Java堆5.方法区6.运行时常量池7.直接内存[2.3.1]对象的创建在虚拟机中,当......