详解Hotspot的经典7种垃圾收集器原理特点与组合搭配

2023-12-05

# 详解Hotspot的经典7种垃圾收集器原理特点与组合搭配

HotSpot共有7种垃圾收集器,3个新生代垃圾收集器,3个老年代垃圾收集器,以及G1,一共构成7种可供选择的垃圾收集器组合。
新生代与老年代垃圾收集器之间形成6种组合,每个新生代垃圾收集器都对应2种组合。

新生代垃圾收集器

所有新生代垃圾收集器,都使用复制算法,都会发生stop-the-world 。由于绝大多数对象的生命周期通常比较短,在新生代被回收的可能性很大,新生代的垃圾回收通常可以回收大部分对象,因此采用复制算法效率更高。

Serial

采用复制算法,GC时发生stop-the-world,使用单个GC线程
“Serial” is a stop-the-world, copying collector which uses a single GC thread.
特点:

  • 客户端模式下的默认新生代收集器
  • 单线程工作(它的“单线程”的意义并不仅仅是说明它 只会使用一个处理器或一条收集线程 去完成垃圾收集工作,更重要的是强调在它进行垃圾收集时, 必须暂停其他所有工作线程 ,直到它收集结束)
  • 简单而高效(与其他收集器的单线程相比)
  • 对于内存资源受限的环境, 它是所有收集器里额外内存消耗(Memory Footprint)最小的
  • 对于单核处理器或处理器核心数较少的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率

⠀Serial/Serial Old收集器协同工作运行示意图如下:

在这里插入图片描述

ParNew

采用复制算法,GC时发生stop-the-world,使用多个GC线程
ParNew 与 Parallel Scavenge的一个主要区别是,ParNew可以与CMS进行搭配使用。
“ParNew” is a stop-the-world, copying collector which uses multiple GC threads. It differs from “Parallel Scavenge” in that it has enhancements that make it usable with CMS. For example, “ParNew” does the synchronization needed so that it can run during the concurrent phases of CMS.
特点:

  • Serial收集器的 多线程并行版本 (除了同时使用多条线程进行垃圾收集之外, 其余的行为(包括Serial收集器可用的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等)都与Serial收集器完全一致,在实现上这两种收集器也共用了相当多的代码)
  • JDK 7之前在 服务端模式下首选的新生代收集器 (一个重要原因:除了Serial收集器外, 目前只有它能与 CMS 收集器配合工作)
  • ParNew收集器是激活CMS后(使用-XX: +UseConcMarkSweepGC选项) 的默认新生代收集器,也可以使用-XX: +/-UseParNewGC选项来强制指定或者禁用它。
  • ParNew收集器在 单核心处理器 的环境中绝对不会有比Serial收集器更好的效果
  • 默认开启的收集线程数与处理器核心数量相同(可以使用-XX: ParallelGCThreads参数来限制垃圾收集的线程数)
    在这里插入图片描述

Parallel Scavenge

采用复制算法,GC时发生stop-the-world,使用多个GC线程 吞吐量优先收集器 ,可控制最大垃圾收集停顿时间(-XX:MaxGCPauseMillis)与吞吐量大小(-XX:GCTimeRatio),支持GC自适应的调节策略(GC Ergonomics,对应参数-XX:+UseAdaptiveSizePolicy)。
“Parallel Scavenge” is a stop-the-world, copying collector which uses multiple GC threads.
特点:

  • 新生代收集器
  • 基于标记-复制算法实现
  • 多线程收集器
  • 吞吐量优先收集器(Parallel Scavenge收集器其他收集器不同在于:CMS等收集器的关注点是尽可能地 缩短垃圾收集时用户线程的停顿时间 , 而Parallel Scavenge收集器的目标则是 达到一个可控制的吞吐量
  • 自适应调节策略(通过+UseAdaptiveSizePolicy参数激活)

ParNew和Parallel Scavenge基本没什么区别,都是年轻代的垃圾回收器,就是在Parallel Scavenge的基础上做了一些简单的增强使其能够较好的配合CMS的使用,ParNew是Parallel Scavenge的一个变种
ParNew响应时间优先,Parallel Scavenge吞吐量优先

吞吐量
吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,即 吞吐量 = 运行用户代码时间 /(运行用户代码时间 + 垃圾收集时间)
假设虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
通常来说,停顿时间越短(低延迟)就越适合需要与用户交互或需要保证服务响应质量的程序, 良好的响应速度能提升用户体验;
而高吞吐量则可以最高效率地利用处理器资源,尽快完成程序的运算任务, 主要适合在后台运算而不需要太多交互的分析任务。

老年代垃圾收集器

除了CMS,其他的老年代垃圾收集器GC时都是stop-the-world,都会在清理垃圾之后进行压缩整理

Serial Old

采用标记整理算法,GC时发生stop-the-world,使用单个GC线程
“Serial Old” is a stop-the-world, mark-sweep-compact collector that uses a single GC thread.
特点:

  • Serial收集器的老年代版本
  • 单线程收集器
  • 使用标记-整理算法
  • 主要在 客户端模式 下使用。如果在 服务端模式 下,它也可能有两种用途: 一种是在JDK 5以及之前的版本中与Parallel Scavenge收集器搭配使用,另外一种就是作为CMS收集器发生失败时的后备预案, 在并发收集发生Concurrent Mode Failure时使用

⠀Serial/Serial Old收集器协同工作运行示意图如下:
在这里插入图片描述

Parallel Old

采用标记整理算法,GC时发生stop-the-world,使用多个GC线程
“Parallel Old” is a compacting collector that uses multiple GC threads.
特点:

  • Parallel Scavenge收集器的老年代版本
  • 多线程并发收集
  • 使用标记-整理算法
  • 在注重吞吐量或者处理器资源较为稀缺的场合, 都可以优先考虑 Parallel Scavenge加Parallel Old收集器 这个组合。

整合和压缩算法
对内存进行整合和压缩是指在垃圾回收过程中对内存中的对象进行整理和重新排列,通过将存活对象向一端移动,以创建更大的连续内存空间,减少内存碎片并提高内存利用率的过程。这通常涉及将对象复制到新的内存空间,然后将原来的内存空间释放。这个过程通常发生在老年代的垃圾回收中。

⠀Parallel Scavenge/Parallel Old 收集器运行示意图如下:
在这里插入图片描述

CMS

CMS采用标记清理算法,是一个以低暂停时间为目标的垃圾收集器。GC时大部分时间并发执行,其中初始化标记和重新标记两个阶段仍然会发生stop-the-world,其余阶段都是并发执行
“CMS” is a mostly concurrent, low-pause collector.
Java之CMS GC的7个阶段: https://mp.weixin.qq.com/s/vmnBlrM7pTtVuyQU-GTcPw

收集流程:
CMS整个过程的四个步骤如下,其中初始标记、 重新标记这两个步骤仍然需要“Stop The World”。
1. 初始标记 -仅仅只是标记一下GC Roots能直接关联到的对象,速度很快
2. 并发标记 -从GC Roots的直接关联对象开始遍历整个对象图的过程,这个过程耗时较长但是不需要停顿用户线程,可以与垃圾收集线程一起并发运行
3. 重新标记 -为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间通常会比初始标记阶段稍长一些, 但也远比并发标记阶段的时间短
4. 并发清除 -清理删除掉标记阶段判断的已经死亡的对象, 由于不需要移动存活对象, 所以这个阶段也是可以与用户线程同时并发的
Concurrent Mark Sweep 收集器运行示意图如下:
在这里插入图片描述

缺点:

  • CMS 收集器 对处理器资源非常敏感 。事实上,面向并发设计的程序都对处理器资源比较敏感。在并发阶段,它虽然不会导致用户线程停顿,但却会因为占用了一部分线程而导致应用程序变慢,降低总吞吐量。
  • 由于CMS收集器 无法处理“浮动垃圾” , 有可能出现“Con-current Mode Failure”失败进而导致另一次完全“Stop The World”的Full GC的产生。
  • CMS是一款基于“标记-清除”算法实现的收集器,这意味着收集结束时 会有大量空间碎片产生 ,空间碎片过多时,将会给大对象分配带来很大麻烦,往往会出现老年代还有很多剩余空间, 但就是无法找到足够大的连续空间来分配当前对象, 而不得不提前触发一次Full GC的情况。

关于CMS收集器浮动垃圾的说明:
由于在CMS的并发标记和并发清理阶段,用户线程是还在继续运行的,程序在运行自然就还会伴随有新的垃圾对象不断产生,但这一部分垃圾对象是出现在标记过程结束以后,CMS无法在当次收集中处理掉它们, 只好留待下一次垃圾收集时再清理掉。这一部分垃圾就称为“浮动垃圾”。
由于在垃圾收集阶段用户线程还需要持续运行, 那就还需要预留足够内存空间提供给用户线程使用, 因此CMS收集器不能像其他收集器那样等待到老年代几乎完全被填满了再进行收集, 必须预留一部分空间供并发收集时的程序运作使用

G1

G1将整个堆划分为多个大小相等的独立区域(Region ),保留新生代和老年代的分代概念(但两者不再是物理隔离的)。
从整体来看是基于标记整理算法,从局部(两个Region之间)来看是基于复制算法 。因此,可以避免产生内存空间碎片,防止发生并发模式失败。
使用多个GC线程,每次优先回收价值最大的Region
支持可预测的停顿时间模型,从而提高收集效率,降低stop-the-world的时间
The Garbage First or G1 garbage collector is available in Java 7 and is designed to be the long term replacement for the CMS collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector that has quite a different layout from the other garbage collectors described previously.

特点:

  • 将堆内存“化整为零”,开创了收集器面向局部收集的设计思路和基于Region的内存布局形式
  • 面向全堆的收集器,不再需要其他新生代收集器的配合工作
  • 主要面向服务端应用的垃圾收集器
  • G1 仍是遵循分代收集理论设计的, 但其堆内存的布局与其他收集器有非常明显的差异
  • G1 不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立Region,每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间或者老年代空间
  • 收集器能够对扮演不同角色的Region采用不同的策略去处理, 这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果
  • Region中还有一类特殊的Humongous区域, 专门用来存储大对象。 G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象。 每个Region的大小可以通过参数-XX: G1HeapRegionSize设定, 取值范围为1MB~32MB, 且应为2的N次幂。 而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的Humongous Region之中, G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待
  • G1收集器之所以能建立可预测的停顿时间模型, 是因为它将Region作为单次回收的最小单元, 即每次收集到的内存空间都是Region大小的整数倍, 这样可以有计划地避免在整个Java堆中进行全区域的垃圾收集
  • G1收集器去跟踪各个Region里面的垃圾堆积的“价值”大小, 价值即回收所获得的空间大小以及回收所需时间的经验值, 然后在后台维护一个优先级列表, 每次根据用户设定允许的收集停顿时间(使用参数-XX: MaxGCPauseMillis指定, 默认值是200毫秒),优先处理回收价值收益最大的那些Region
  • 可以由用户指定期望的停顿时间是G1收集器很强大的一个功能,设置不同的期望停顿时间, 可使得G1在不同应用场景中取得关注吞吐量和关注延迟之间的最佳平衡(默认的停顿目标为两百毫秒,通常把期望停顿时间设置为一两百毫秒或者两三百毫秒会是比较合理的)

G1 收集器 Region 分区示意图如下:
在这里插入图片描述

G1 收集器的运作过程主要步骤如下:

  • 初始标记 仅仅只是标记一下GC Roots能直接关联到的对象 ,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。这个阶段需要停顿线程,但耗时很短,而且是借用进行Minor GC的时候同步完成的,所以G1收集器在这个阶段实际并没有额外的停顿。
  • 并发标记 从GC Root开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象 ,这阶段耗时较长,但可与用户程序并发执行。 当对象图扫描完成以后,还要重新处理SATB记录下的在并发时有引用变动的对象。
  • 最终标记 :对用户线程做另一个短暂的暂停,用于 处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。
  • 筛选回收 : 负责更新Region的统计数据,对各个Region的回收价值和成本进行排序, 根据用户所期望的停顿时间来制定回收计划, 可以自由选择任意多个Region构成回收集,然后 把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间 。这里的操作涉及存活对象的移动,是必须暂停用户线程,由多条收集器线程并行完成的。

⠀从上述阶段的描述可以看出, G1收集器除了并发标记外, 其余阶段也是要完全暂停用户线程的,换言之, 它并非纯粹地追求低延迟, 官方给它设定的目标是在延迟可控的情况下获得尽可能高的吞吐量。

G1 收集器运行示意图如下:
在这里插入图片描述

G1 收集器与 CMS 收集器的异同

  • 两者都非常关注停顿时间的控制
  • G1 可以指定最大停顿时间、 分Region的内存布局、 按收益动态确定回收集
  • 与CMS的“标记-清除”算法不同, G1从整体来看是基于“标记-整理”算法实现的收集器,但从局部(两个Region之间)上看又是基于“标记-复制”算法实现 ,无论如何,这两种算法都意味着G1运作期间不会产生内存空间碎片,垃圾收集完成之后能提供规整的可用内存。这种特性有利于程序长时间运行,在程序为大对象分配内存时不容易因无法找到连续内存空间而提前触发下一次收集
  • G1和CMS都使用卡表来处理跨代指针 ,但G1的卡表实现更为复杂,而且堆中每个Region,无论扮演的是新生代还是老年代角色,都必须有一份卡表,这导致 G1的记忆集(和其他内存消耗)可能会占整个堆容量的20%乃至更多的内存空间 ,而CMS的卡表就相当简单,只有唯一一份, 只需要处理老年代到新生代的引用, 反过来则不需要
  • 它们都使用到写屏障,CMS用写后屏障来更新维护卡表;而G1除了使用写后屏障来进行同样的(由于G1的卡表结构复杂,其实是更烦琐的)卡表维护操作外,为了实现原始快照搜索(SATB)算法,还需要使用写前屏障来跟踪并发时的指针变化情况。相比起增量更新算法, 原始快照搜索能够减少并发标记和重新标记阶段的消耗 ,避免CMS那样在最终标记阶段停顿时间过长的缺点,但是在用户程序运行过程中确实会产生由跟踪引用变化带来的额外负担。

垃圾回收器器组合搭配

Serial Old(MSC)可以与所有新生代收集器进行组合,共3种组合

JVM仅指定新生代垃圾收集器的情况下,默认老年代采用Serial Old垃圾收集器(带压缩)

-XX:+UseSerialGC

Serial (DefNew) + Serial Old(Serial Mark Sweep Compact)

-XX:+UseParNewGC

Parallel (ParNew) + Serial Old(Serial Mark Sweep Compact)

-XX:+UseParallelGC

Parallel Scavenge (PSYoungGen) + Serial Old(Serial Mark Sweep Compact (PSOldGen))
注:在Parallel Scavenge收集器架构中本身有PS MarkSweep收集器来进行老年代收集,但由于PS MarkSweep与Serial Old实现非常接近,因此官方的许多资料都直接以Serial Old代替PS MarkSweep进行讲解。

Parallel Old(带压缩)只能与Parallel Scavenge进行组合

-XX:+UseParallelOldGC

Parallel Scavenge (PSYoungGen) + Parallel Mark Sweep Compact (ParOldGen)

CMS(不带压缩)可以与Serial和ParNew进行组合,共2种组合

-XX:-UseParNewGC -XX:+UseConcMarkSweepGC

Serial (DefNew) + CMS(Concurrent Mark Sweep)

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

Parallel (ParNew) + CMS(Concurrent Mark Sweep) + Serial Old(Serial Mark Sweep Compact)

G1(Garbage First),不需要搭配其他垃圾收集器

-XX:+UseG1GC

6种垃圾收集组合关系图

在这里插入图片描述

在这里插入图片描述

推荐使用的2种GC组合

1.基于低停顿时间的垃圾收集器

-XX:+UseConcMarkSweepGC(该参数隐式启用-XX:+UseParNewGC)

2.基于吞吐量优先的垃圾收集器

-XX:+UseParallelOldGC(该参数隐式启用-XX:+UseParallelGC)

在这里插入图片描述

总结

下面对这七种垃圾收集器进行了一个总结,具体如下表所示。

收集器 串行、并行、并发 新生代/老年代 算法 目标 使用场景
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时再Server模式下与CMS配合
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
Serial Old 串行 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式 CMS的后备预案
Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
CMS 并发 老年代 标记-清除 响应速度优先 集中在互联网站或B/S系统服务端上
G1 并发 新生代/老年代 标记-整理/复制算法 响应速度优先 面向服务端应用,用来替换CMS

参考
HotSpot的7种垃圾收集器组合
浅析经典JVM垃圾收集器-Serial/ParNew/Parallel Scavenge/Serial Old/Parallel Old/CMS/G1
https://blogs.oracle.com/
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
https://www.splunk.com/en_us/products/apm-application-performance-monitoring.html?source=plumbr
《深入理解Java虚拟机 JVM高级特性与最佳实践》周志明
《Java性能权威指南》
Java之CMS GC的7个阶段: https://mp.weixin.qq.com/s/vmnBlrM7pTtVuyQU-GTcPw

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

详解Hotspot的经典7种垃圾收集器原理特点与组合搭配 的相关文章

随机推荐

  • 2024艾奇KTV电子相册制作软件(只需三步)懒人专用电子相册制作神器

    艾奇KTV电子相册视频制作软件是一款超级强大的电子相册和MV视频制作软件 你可以把你的照片和视频配上音乐和歌词字幕 做成各种格式的视频电子相册 只需三个简单的步骤 您就可以输出各种分辨率和清晰度的高质量视频相册 如4K 1080P高清和手机
  • Sui生态DeFi将参加Builder DAO举办的活动,为期三天畅谈如何Build on Sui

    LeadUp the Night是一个定期举办的MeetUp活动 由Builder DAO邀请区块链各方项目开发者 VC担任本活动的讲师 这个活动旨在促进区块链技术的发展和应用 让参与者有机会开发创新的区块链应用 探索区块链技术的潜力 12
  • 了解拼图软件哪个好用吗?这篇文章带你了解

    当你回忆起童年时光 是否还记得那些用色彩斑斓的拼图组装起来的欢乐时刻呢 那种将碎片聚合在一起的成就感和对完整画面的渴望 仿佛成为了我们生活中最美妙的拼图 而如今 科技进步非常的快速 我们已经不再需要纸板和拼图片 而是可以通过电子设备来进行拼
  • Java多线程并行读取多个文件(二)

    目录 一 Java多线程并行读取多个文件 二 AsynchronousFileChannel 详解 三 异步文件读取 一 Java多线程并行读取多个文件 在考虑性能问题时 多线程并行读取多个文件的实现需要注意一些关键因素 以充分发挥多线程并
  • 文件搜索神器—Everything,结合内网穿透秒变在线搜索神器!

    Everything cpolar搭建在线资料库 实现随时随地访问 文章目录 Everything cpolar搭建在线资料库 实现随时随地访问 前言 1 软件安装完成后 打开Everything 2 登录cpolar官网 设置空白数据隧道
  • Latex正文引用图片编号,防止某张图片删除或调整导致正文序号对应错误

    一 背景 Latex真的是非常好用的论文排版工具 虽然不像word一样是 所见即所得 的可视化方式 但完全不用管格式 包括图片的排版 文字的缩进等等 这在word里调整起来真的是非常麻烦 特别是某个段落 图片修改后 又要重新调整格式 非常的
  • Ubuntu20.04安装向日葵、开机自启、解决windows系统远程黑屏(笔记)

    这里写目录标题 动机 1 Ubuntu20 04 安装向日葵 2 设置开机自启 3 解决windows不可远程的问题 4 大公告成 动机 办公室有个工作站 要比我的笔记本的CPU稍微好一点 用来跑陆面过程 我信心满满的装了个Ubuntu20
  • 什么是离岸公司?有什么作用?

    离岸公司是泛指在离岸法区内依据其离岸公司法规范成立的有限责任公司或股份有限公司 这些公司不能在注册地经营 而主要是在离岸法区以外的地方开展业务活动 离岸公司的主要特点包括高度保密性 无外汇管制和减免税务负担 离岸公司的作用主要有以下几个方面
  • 销售人员一定要知道的6种获取电话号码的方法

    对于销售来说 电话销售是必须要知道的销售方法 也是销售生涯中的必经之路 最开始我们并不清楚这么电话是从哪里来的 也不清楚是通过哪些方法渠道获取 那么今天就来分享给各位销售人员获取客户电话号码的方法 1 打印自己的名片 在工作当中少不了接触其
  • 5.【自动驾驶与机器人中的SLAM技术】2D点云的scan matching算法 和 检测退化场景的思路

    目录 1 基于优化的点到点 线的配准 2 对似然场图像进行插值 提高匹配精度 3 对二维激光点云中会对SLAM功能产生退化场景的检测 4 在诸如扫地机器人等这样基于2D激光雷达导航的机器人 如何处理悬空 低矮物体 5 也欢迎大家来我的读书号
  • 大Ⅲ周记11

    1 本周学习了mysql数据库操作的相关知识 根据课设要求完成了压降系统数据库表的设计 2 计算机网络完成了所有章节的作业 开始进入复习阶段 预计下周完成一至二章的复习作业
  • leetcode:93. 复原 IP 地址

    复原 IP 地址 中等 1 4K 相关企业 有效 IP 地址 正好由四个整数 每个整数位于 0 到 255 之间组成 且不能含有前导 0 整数之间用 分隔 例如 0 1 2 201 和 192 168 1 1 是 有效 IP 地址 但是 0
  • 最近在对接电商供应链,说说开放平台API接口

    B2B电商开放平台的设计需要从以下几面去思考 开放平台API接口 的接入 主要是从功能需求的角度 设计满足业务需求的接口及对应的字段 平台与商家之间信息的对接 对接的方法有哪些 对接过程中需要可能会遇到什么问题 同步开关及权限的设计 处理信
  • 鸿蒙4.0开发笔记之ArkTS装饰器语法基础@Prop@Link@State状态装饰器(十二)

    文章目录 一 哪些是状态装饰器 二 State Prop Link状态传递的核心规则 三 状态装饰器练习 一 哪些是状态装饰器 1 State 被装饰拥有其所属组件的状态 可以作为其子组件单向和双向同步的数据源 当其数值改变时 会引起相关组
  • Nessus简单介绍与安装

    1 Nessus简介 Nessus号称是世界上最流行的漏洞扫描程序 全世界有超过75000个组织在使用它 该工具提供完整的电脑漏洞扫描服务 并随时更新其漏洞数据库 Nessus不同于传统的漏洞扫描软件 Nessus可同时在本机或远端上遥控
  • WebGL笔记:矩阵平移的数学原理和实现

    矩阵平移的数学原理 让向量OA位移 x方向 tx y方向 ty z方向 tz 最终得到向量OB 矩阵平移的应用 再比如我要让顶点的x移动0 1 y移动0 2 z移动0 3 1 顶点着色器核心代码
  • 有效表达观点的艺术

    有效表达观点的艺术 在人际交往中 有效地表达自己的观点是建立良好关系和实现有效沟通的关键 然而 这并不总是易如反掌 有时候 我们可能会遇到表达困难 或者我们的观点可能被误解 本文将探讨如何有效地表达观点 以及掌握说话的艺术的重要性 首先 清
  • 人工智能:开启未来商业新篇章

    人工智能 开启未来商业新篇章 随着科技的快速发展 人工智能 AI 在商业领域的应用越来越广泛 成为企业把握未来商业机遇的重要方向 本文将探讨人工智能如何重塑商业格局 为企业提供新的增长点 以及企业如何抓住AI的商业契机 一 AI重塑商业格局
  • 机器人学英语

    我的prompt i want to you act as an english language teacher asistant to help me study english you could teach me in such a
  • 详解Hotspot的经典7种垃圾收集器原理特点与组合搭配

    详解Hotspot的经典7种垃圾收集器原理特点与组合搭配 HotSpot共有7种垃圾收集器 3个新生代垃圾收集器 3个老年代垃圾收集器 以及G1 一共构成7种可供选择的垃圾收集器组合 新生代与老年代垃圾收集器之间形成6种组合 每个新生代垃圾