• GC+JVM


    1.内存管理模型

    ①以对象的方式管理内存,每个对象占据内存中连续的一段,分配在堆中。对象引用可以指向堆中的其他对象。非基本数据类型的对象等价于数据引用。

    ②基于栈和堆的内存管理都是动态分配,即在运行时动态分配内存,建立新的内存对象。而静态内存分配在编译阶段就已经确定好了内存分配。

    ③每个线程都有其线程栈,各自管理,彼此之间不可见。多线程之间传递数据,通过复制而非引用。栈无法支持复杂的数据类型。所有的局部的基本数据类型都在栈上创建。

    ④本地方法栈、PC

    ⑤Method Area(hotspot中称为perm,是堆的一部分,后改名metaspace)储存类信息、常量、静态变量。

    总结各个变量、引用的存储位置:

    栈:方法中基本类型变量及其值,方法中引用类型变量的引用

    堆:方法中引用类型变量的实体对象,类的非静态成员变量(包括基本类型变量,引用类型变量)

    方法区(也可以说是堆中):已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据

     2.GC中的基本概念

    ①根对象:判断可达性的起点,主要包括寄存器、静态区域数据、栈中数据所指的对象

    ②可达对象(活对象):从root可达的对象
    ③不可达对象(死对象):从root不可达的对象
    ④幽灵时间:对象从不可达到被回收的时间

    3.四种GC策略

    ①引用计数:

    为每个对象储存一个计数器,当有其他引用指向他的时候计数器+1,当其他引用与其断开连接时计数器-1,当计数器为0时回收。

    优点:幽灵时间短

    缺点:不全面容易漏、对并发支持弱、占用额外内存空间较大。

    ②标记-清除:

    分为标记、清除两个阶段。标记阶段就是标注对象的活性(每个对象有一个标记位)。清除阶段就是清除被标记为死亡的对象。

    优点:便于理解、操作时间短、与mutator松耦合、不移动对象。

    缺点:需要停止程序以进行mark和sweep,导致幽灵时间过长,影响了程序本身的性能;造成了内存碎片化。

    ③标记-整理

    和标记清除基本相似,唯一的区别在于回收的时候,把垃圾全都放到前面,把有用的放到后面,然后把前面的收走。

    优点:避免碎片化

    缺点:时间开销大,影响程序性能。

     ④复制

    它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉。

    优点:不容易产生内存碎片、分配内存开销比较小

    缺点:空间开销大、随着对象数量的增加复制的代价也不断增大。

     4.内存分区

    分为新生代、老生代、永久代。

    ①新生代

    又分为伊甸园、两个存活区

    为了减少gc代价,使用copy进行垃圾回收。

    当java分配对象堆内存的时候,首先在伊甸园进行分配。

    当伊甸园满的时候,启动Minor GC,将伊甸园中的被引用的对象转移到S0生存区

    伊甸园再次满的时候,第二次启动Minor GC,伊甸园和S0中的被引用对象转移到S1生存区。

    第三次启动的时候,伊甸园和S1中的被引用对象转移到S0生存区。

    如此进行下去,对于一个对象来说,他每在垃圾回收中存活一次,它的“代”就增加一次。

    如果一个对象的代的数量超过某个临界值,下一次Minor GC中它将被转移到老生代。

     ②老生代

    这一部分一般采用标记-整理、标记-清理等算法。

     由新生代中代数比较大的对象复制而来。

    如果老生代满了,就会触发Full GC

    如果这一部分满了,则无法触发Minor GC

    ③永久代

    如果这一部分满了,即无法分配更多储存元数据的空间,也启动Full GC

    5.JVM性能调优

    主要着手于垃圾处理部分,控制GC时长、GC频率

    指定大小时,一般用<n>[g|m|k]这种形式,分别对应nGB,nMB,nKB这三种大小

    System.gc()可以手动请求垃圾回收。

    常用命令行参数:

    -verbose:gc 输出每次gc的信息

    -Xms<size> 初始堆大小

    -Xmx<size> 最大堆大小

    -XX:NewSize=<size> 初始年轻代大小(老生代初始大小为xms-newsize)

    -XX:MaxNewSize=<size> 最大年轻代大小(老生代最大大小为xmx-maxnewsize)

    -XX:NewRatio=<n> 新生代与老生代的比例是1:n,即新生代占堆的总内存的1/(n+1)

    -XX:SurvivorRatio=<n> 伊甸园与存活区的比例是n:1,即每个存活区占新生代的1/(2+n)

    -XX:MaxHeapFreeRatio=<n> 在一个代中,如果空闲内存的比例超过n%,这个代就会压缩,把空闲内存比例维持在n%以下

    -XX:MinHeapFreeRatio=<n>在一个代中,如果空闲内存的比例低于n%,这个代就会扩张,把空闲内存的比例维持在n%以上

    -XX:+PrintGC 打印GC信息

    -XX:+PrintGCDetails 打印GC详细信息

    -Xloggc:filename 将GC信息打印到日志文件中去

    -XX:+UseSerialGC 对所有gc使用串行处理

    -XX:+UseParallelGC -XX:ParallelGCThreads=n 对新生代使用并行GC算法,并制定线程数

    XX:+UseParallelOldGC 对新生代、老生代都使用并行GC算法。

    -XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=n 对老生代使用多线程的标记-清理算法,并指定线程数量。

    –XX:+UseG1GC 对于较大容量的堆使用的一种新的垃圾回收算法。

  • 相关阅读:
    天天生鲜项目需求分析——基于Django框架的天天生鲜电商网站项目系列博客(一)
    预训练模型专题_GPT2_模型代码学习笔记
    Logistic模型原理详解以及Python项目实现
    【人生苦短,我学 Python】基础篇——基本语句(Day5)
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    程序员常用的六大技术博客类
    [慕课笔记]Node入口文件分析和目录初始化
    如何在面试中脱颖而出?
    程序媛,坚持这几个好习惯让你越来越美
    2017前端精品面试文章总结
  • 原文地址:https://www.cnblogs.com/hyfer/p/11075096.html
Copyright © 2020-2023  润新知