CN117597671A - Z垃圾收集器中的开始时快照标记 - Google Patents

Z垃圾收集器中的开始时快照标记 Download PDF

Info

Publication number
CN117597671A
CN117597671A CN202280046339.8A CN202280046339A CN117597671A CN 117597671 A CN117597671 A CN 117597671A CN 202280046339 A CN202280046339 A CN 202280046339A CN 117597671 A CN117597671 A CN 117597671A
Authority
CN
China
Prior art keywords
parity
tag
class
heap
current
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202280046339.8A
Other languages
English (en)
Inventor
E·厄斯特伦德
P·利登
S·M·R·卡尔松
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Oracle International Corp
Original Assignee
Oracle International Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Priority claimed from US17/303,635 external-priority patent/US11734171B2/en
Application filed by Oracle International Corp filed Critical Oracle International Corp
Priority claimed from PCT/US2022/029484 external-priority patent/WO2022245749A1/en
Publication of CN117597671A publication Critical patent/CN117597671A/zh
Pending legal-status Critical Current

Links

Landscapes

  • Devices For Executing Special Programs (AREA)

Abstract

在执行垃圾收集标记期间,应用线程接收用于覆写对象的引用字段的第一请求,该对象至少包括第一引用,并且第一请求包括要写入到引用字段的第二引用。响应于接收到第一请求,应用线程确定垃圾收集标记处理正在遍历的对象的标记奇偶校验并从堆中加载第一引用。应用线程确定第一引用的标记元数据与标记奇偶校验不匹配。响应于该确定,应用线程将第一引用添加到标记列表、修改第二引用以包括当前标记奇偶校验作为标记元数据,并且将修改后的第二引用存储到第一引用字段。在对引用字段的后续写入中,应用线程避免添加到标记列表。

Description

Z垃圾收集器中的开始时快照标记
通过引用并入;免责声明
以下申请特此通过引用并入:2021年6月3日提交的申请No.17/303,635;2021年5月19日提交的申请No.63/190,617;2021年5月19日提交的申请No.63/190,621;2021年5月19日提交的申请No.63/190,625。申请人特此撤销母申请或其审查历史中的权利要求范围的任何免责声明,并告知美国专利商标局(USPTO),本申请中的权利要求可能比母申请中的任何权利要求更广泛。
技术领域
本公开涉及垃圾收集器。特别地,本公开涉及优化的开始时快照(snapshot atthe beginning,SATB)标记处理。
背景技术
编译器将根据旨在方便程序员的规范所编写的源代码转换成机器代码(也称为“本机(native)代码”或“目标代码”)。机器代码可直接由物理机器环境执行。附加地或替代地,编译器将源代码转换成中间表示(也称为“虚拟机代码/指令”),诸如字节码,其可由能够在各种物理机器环境之上运行的虚拟机执行。虚拟机指令可由虚拟机以比源代码更直接和更高效的方式执行。将源代码转换成虚拟机指令包括根据规范将源代码功能映射到虚拟机功能,这利用了虚拟机的底层资源(诸如数据结构)。通常,程序员经由源代码以简单术语呈现的功能被转换成更复杂的步骤,这些步骤更直接地映射到虚拟机所驻留的底层硬件所支持的指令集。
虚拟机通过执行源代码的中间表示(诸如字节码)来执行应用和/或程序。虚拟机的解释器将中间表示转换成机器代码。在执行应用时,会为程序所创建的对象分配一定的存储器(也称为“堆存储器”)。垃圾收集系统可以用于自动回收应用不再使用的对象所占用的存储器位置。垃圾收集系统使程序员不必明确指定要释放的对象。分代垃圾收集方案基于大多数对象仅在短时间段被使用的经验观察。在分代垃圾收集中,指定两个或更多个分配区域(代),并基于其中包含的对象的年龄将其保持分离。新对象在定期收集的“年轻”代中被创建,并且当一代满时,仍被存储在较老一代区域中的一个或多个对象所引用的对象被复制到(即“提升到”)下一个最老的一代。有时会执行完整扫描。
在本部分中描述的方法是可以实行的方法,但不一定是先前已经构想或实行的方法。因此,除非另外指出,否则不应当假设在本部分中描述的任何方法仅仅因为其包括在本部分中就被认为是现有技术。
附图说明
在附图的各个图中,实施例是作为示例而不是作为限制进行图示的。应当注意的是,在本公开中对“一个”实施例的引用不一定是指相同的实施例,并且它们意味着至少一个。在附图中:
图1图示了其中可以实践本文描述的技术的示例计算架构。
图2是图示适合于实现本文描述的方法和特征的计算机系统的一个实施例的框图。
图3图示了根据实施例的以框图形式的示例虚拟机存储器布局。
图4图示了根据实施例的以框图形式的示例帧。
图5图示了根据实施例的虚拟机的执行引擎和堆存储器。
图6图示了根据实施例的堆引用和可解除引用的引用。
图7图示了根据实施例的引用加载屏障。
图8图示了根据实施例的引用写屏障。
图9图示了根据实施例的当通过应用线程写入堆引用时使用写屏障来改进开始时快照(SATB)GC标记处理的一组操作。
图10图示了根据一个或多个实施例的系统。
具体实施方式
在以下描述中,为了解释的目的,阐述了许多具体细节以便提供透彻的理解。可以在没有这些具体细节的情况下实践一个或多个实施例。在一个实施例中描述的特征可以与在不同实施例中描述的特征组合。在一些示例中,参考框图形式来描述众所周知的结构和设备,以便避免不必要地模糊本发明。
1.总体概述
2.架构概述
2.1 示例类文件结构
2.2 示例虚拟机架构
2.3加载、链接和初始化
3.垃圾收集
4.加载屏障和写屏障
5.根据实施例的当通过应用线程写入堆引用时使用写屏障来改进开始时快照(SATB)GC标记处理
6.其它方面;扩展
7.硬件概述
1.总体概述
虚拟机通过执行源代码的中间表示(诸如字节码)来执行应用和/或程序。虚拟机的解释器将中间表示转换成机器代码。当执行应用时,为程序所创建的对象分配一定的存储器(也称为“堆存储器”)。垃圾收集系统可以用于自动回收应用不再使用的对象所占用的存储器位置。出于存储对象的目的,堆存储器可以被划分为多代。特别地,堆存储器可以包括被指定为“年轻代”的部分,用于存储新创建的对象,以及被指定为“老年代”的部分,用于存储较老的对象。在实施例中,多代垃圾收集器可以通过遍历整个堆存储器或者通过仅遍历堆存储器的一部分来收集垃圾。例如,垃圾收集器可以仅遍历堆存储器的被指定为年轻代的部分。
一个或多个实施例包括基于与堆引用一起存储的垃圾收集状态(也称为“颜色”)执行垃圾收集。一组垃圾收集(GC)状态用于跟踪关于堆引用的GC操作的进度。堆引用包括与堆引用相关联的GC状态的指示。
垃圾收集(GC)周期包括标记阶段。在标记阶段期间,GC用“存活”位标记每个存活对象。GC首先选择新的标记奇偶校验。然后,GC识别一组所有根(例如,一组直接引用程序中对象的指针)。GC遍历堆,从根开始、与突变(mutator)并发操作、通过至少调整存储在与对象相关联的引用中的颜色以包含新的标记奇偶校验来将每个对象标记为存活。但是,在与突变线程并发运行时标记堆上的对象会变得更加复杂,因为当GC正在遍历堆时,突变线程可能会更改堆的结构。开始时快照(SATB)是一种GC标记在标记阶段开始时存活的任何对象的技术。这可能导致在标记期间不再存活的对象仍被标记为存活,但防止了存活对象未被标记的情况。
一个或多个实施例包括当将引用写入到堆存储器上时实现引用写屏障。可能与GC线程并发运行的应用线程请求修改堆存储器中的引用。如上所述,堆引用包括指示堆引用被存储时的GC状态的“颜色”。写屏障在覆写引用之前检查引用的颜色。如果引用的颜色与由GC指示的良好颜色不匹配,那么写屏障采用慢速路径,该路径(a)将堆存储器内对象字段的原始内容记录到SATB列表中(例如,紧接在接收到写入指令之前),并且(b)修改写入指令中接收到的引用以包括良好颜色,以及(c)将修改后的引用(例如,包括良好颜色)存储到堆。如果引用的颜色与由GC指示的良好颜色相匹配,那么写屏障采用快速路径,该路径(a)将修改后的引用(包括良好颜色)写入到堆,并且(b)避免添加到SATB列表。GC通过标记SATB列表中的所有对象并在必要时遍历它们的引用来处理SATB列表。当GC完成堆的遍历和SATB列表的处理两者时,GC已将标记阶段开始时存活的所有对象标记为存活对象。以这种方式,写屏障可以确保只有修改引用的第一次写才会使得GC将条目添加到SATB列表。
一个或多个实施例包括在将引用从堆存储器加载到调用栈时实现引用加载屏障。可以与GC线程并发运行的应用线程请求将引用从堆存储器加载到调用栈上。对来自堆存储器的引用执行一组操作,(a)确定由颜色指示的GC状态相对于当前GC周期的当前阶段是否“良好”(例如,与当前GC周期的当前阶段的至少一部分匹配),以及(b)通过从引用中移除颜色来修改引用。如果颜色所指示的GC状态不为良好,那么执行一组GC操作以使堆引用从当前状态变为良好GC状态,并且更新堆引用以指示良好GC状态。此后,修改后的引用被存储到调用栈上。调用栈上的与堆引用指向同一对象的引用不包括GC状态中的任何GC状态的任何指示。
在本说明书中描述和/或在权利要求中叙述的一个或多个实施例可能不包括在该总体概述部分中。
2.架构概述
图1图示了在其中可以实践本文描述的技术的示例架构。关于示例架构所描述的软件和/或硬件组件可以被省略或与和本文所描述的一组功能不同的一组功能相关联。根据一个或多个实施例,可以在环境内使用本文中未描述的软件和/或硬件组件。因此,示例环境不应当被认为是限制任何权利要求的范围。
如图1所示,计算架构100包括源代码文件101,源代码文件由编译器102编译成类文件103,这些类文件表示要被执行的程序。类文件103然后由执行平台112加载和执行,该执行平台包括运行时环境113、操作系统111以及使得能够在运行时环境113和操作系统之间通信的一个或多个应用编程接口(API)110。运行时环境113包括虚拟机104,该虚拟机包括各种组件,诸如存储器管理器105(其可以包括垃圾收集器)、用于检查类文件103的有效性的类文件验证器106、用于定位和构建类的内存(in-memory)表示的类加载器107、用于执行虚拟机104代码的解释器108以及用于产生经优化的机器级别代码的即时(just-in-time,JIT)编译器109。
在实施例中,计算架构100包括源代码文件101,源代码文件包含已经用特定编程语言(诸如Java、C、C++、C#、Ruby、Perl等)编写的代码。因此,源代码文件101遵循用于该相关联的语言的一组特定语法和/或语义规则。例如,用Java编写的代码遵循Java语言规范。但是,由于规范随着时间的推移被更新和修订,因此源代码文件101可能与指示源代码文件101所遵循的规范的修订版本的版本号相关联。被用于编写源代码文件101的确切编程语言通常不是关键的。
在各种实施例中,编译器102将根据旨在方便程序员的规范所编写的源代码转换为可由特定机器环境直接执行的机器代码或目标代码,或者可由能够在各种特定机器环境之上运行的虚拟机104执行的中间表示(“虚拟机代码/指令”)(诸如字节码)。虚拟机指令可由虚拟机104以比源代码更直接和高效的方式执行。将源代码转换为虚拟机指令包括将源代码功能从该语言映射到利用底层资源(诸如数据结构)的虚拟机功能。通常,程序员经由源代码以简单术语呈现的功能被转换为更复杂的步骤,这些步骤更直接地映射到虚拟机104所驻留的底层硬件所支持的指令集。
一般而言,程序作为经编译的程序或者经解释的程序来执行。当程序被编译时,代码在执行之前从第一语言全局地变换为第二语言。由于变换代码的工作是提前执行的,所以经编译的代码往往具有优异的运行时性能。此外,由于该变换在执行之前全局地发生,因此可以使用诸如常量合并(constant folding)、死代码消除(dead code elimination)、内联(inlining)等技术来分析和优化该代码。但是,取决于被执行的程序,启动时间(start-up time)可能很长。此外,插入新代码将需要使程序下线(offline)、重新编译和重新执行。对于被设计为允许代码在程序执行期间被插入的许多动态语言(诸如Java),纯编译的方法可能是不合适的。当程序被解释时,程序的代码在程序执行的同时被逐行读取并且转换为机器级别指令。因此,程序具有短的启动时间(可以几乎立即开始执行),但是运行时性能由于在工作中(on the fly)执行变换而降低。此外,由于每个指令被单独地分析,因此依赖于对程序的更全局分析的许多优化不能被执行。
在一些实施例中,虚拟机104包括解释器108和JIT编译器109(或实现这两个方面的组件),并且使用解释技术和编译技术的组合来执行程序。例如,虚拟机104可以初始地通过经由解释器108解释表示程序的虚拟机指令来开始,同时跟踪与程序行为相关的统计信息,诸如不同的代码部分或代码块多频繁地被虚拟机104执行。一旦代码块超过阈值(变“热”),虚拟机104就调用JIT编译器109来执行对该块的分析并且生成经优化的机器级别指令,这些经优化的机器级别指令代替“热”代码块被用于将来的执行。由于程序往往花费大部分时间执行整个代码的一小部分,因此只编译程序的“热”部分可以提供与完全编译代码相似的性能,但没有启动惩罚。此外,尽管优化分析被约束到“热”块被代替,但是仍然存在比单独转换每个指令大得多的优化潜力。在上述示例中存在多种变体,诸如分层编译。
为了提供清楚的示例,源代码文件101已经被图示为要由执行平台112执行的程序的“顶级”表示。虽然计算架构100将源代码文件101绘为“顶级”程序表示,但是在其它实施例中,源代码文件101可以是经由将不同语言的代码文件处理成源代码文件101的语言的“更高级”编译器接收到的中间表示。以下公开中的一些示例假设源代码文件101遵循基于类的面向对象的编程语言。但是,这不是对利用本文所描述的特征的要求。
在实施例中,编译器102接收源代码文件101作为输入,并且将源代码文件101转换为以虚拟机104所期望的格式的类文件103。例如,在JVM的上下文中,Java虚拟机规范定义了类文件103预期要遵循的特定类文件格式。在一些实施例中,类文件103包含已从源代码文件101转换的虚拟机指令。但是,在其它实施例中,类文件103也可以包含其它结构,诸如识别常量值的表和/或与各种结构(类、字段、方法等)相关的元数据。
以下讨论假设类文件103中的每一个类文件表示在源代码文件101中定义的(或由编译器102/虚拟机104动态生成的)相应的“类”。但是,前述假设不是严格的要求并且将取决于虚拟机104的实现方式。因此,无论类文件103的确切格式如何,本文描述的技术都仍然可以被执行。在一些实施例中,类文件103被划分为一个或多个“库(library)”或“包(package)”,其中的每一个库或包包括提供相关功能的类的集合。例如,库可以包含实现输入/输出(I/O)操作、数学工具、密码技术、图形实用工具等的一个或多个类文件。此外,一些类(或这些类中的字段/方法)可以包括访问限制,这些访问限制将类的使用限制在特定类/库/包内或限制到具有适当权限的类。
2.1示例类文件结构
图2图示了根据实施例的以框图形式的类文件200的示例结构。为了提供清楚的示例,本公开的其余部分假设计算架构100的类文件103遵循本部分中所描述的示例类文件200的结构。但是,在实际环境中,类文件200的结构将取决于虚拟机104的实现方式。此外,本文所讨论的一个或多个特征可以修改类文件200的结构,以例如添加附加的结构类型。因此,类文件200的确切结构对于本文描述的技术不是关键的。为了第2.1部分的目的,“类”或“当前类”是指由类文件200表示的类。
在图2中,类文件200包括常量表201、字段结构208、类元数据207和方法结构209。在实施例中,常量表201是除了其它功能之外还充当类的符号表的数据结构。例如,常量表201可以存储与在源代码文件101中使用的各种标识符相关的数据,诸如类型、范围、内容和/或位置。常量表201具有用于值结构202(表示类型int、long、double、float、byte、string等的常量值)、类信息结构203、名称和类型信息结构204、字段引用结构205、以及由编译器102从源代码文件101导出的方法引用结构206的条目。在实施例中,常量表201被实现为将索引i映射到结构j的数组。但是,常量表201的确切实现不是关键的。
在一些实施例中,常量表201的条目包括对其它常量表201条目进行索引的结构。例如,用于表示字符串的值结构202之一的条目可以保持将其“类型”识别为字符串的标签以及如下索引,该索引指向常量表201中的、存储表示该字符串的ASCII字符的char、byte或int值的一个或多个其它值结构202。
在实施例中,常量表201的字段引用结构205在常量表201中保持指向表示对字段进行定义的类的类信息结构203之一的索引,以及在常量表201保持指向提供字段的名称和描述符的名称和类型信息结构204之一的索引。常量表201的方法引用结构206在常量表201中保持指向表示对方法进行定义的类的类信息结构203之一的索引,以及在常量表201中保持指向提供方法的名称和描述符的名称和类型信息结构204之一的索引。类信息结构203在常量表201中保持指向保持相关联的类的名称的值结构202之一的索引。
名称和类型信息结构204在常量表201中保持指向存储字段/方法的名称的值结构202之一的索引,以及在常量表201中保持指向存储描述符的值结构202之一的索引。
在实施例中,类元数据207包括类的元数据,诸如(一个或多个)版本号、常量池中的条目数量、字段数量、方法数量、访问标志(类是否是公开的(public)、私有的(private)、最终的(final)、抽象的(abstract)等)、指向识别当前类的常量表201的类信息结构203之一的索引、指向识别超类(superclass)(如果有的话)的常量表201的类信息结构203之一的索引,等等。
在实施例中,字段结构208表示识别类的各种字段的一组结构。字段结构208为类的每个字段存储该字段的访问器标志(字段是否是静态的(static)、公开的(public)、私有的(private)、最终的(final)等)、在常量表201中指向保持该字段的名称的值结构202之一的索引、以及在常量表201中指向保持该字段的描述符的值结构202之一的索引。
在实施例中,方法结构209表示识别类的各种方法的一组结构。方法结构209为类的每个方法存储该方法的访问器标志(例如,方法是否是静态的(static)、公开的(public)、私有的(private)、同步的(synchronized)等)、在常量表201中指向保持方法的名称的值结构202之一的索引、在常量表201中指向保持方法的描述符的值结构202之一的索引、以及与在源代码文件101中定义的方法的主体对应的虚拟机指令。
在实施例中,描述符表示字段或方法的类型。例如,描述符可以实现为遵循特定语法的字符串。虽然确切的语法不是重要的,但以下将描述几个示例。
在描述符表示字段的类型的示例中,描述符识别由该字段保持的数据的类型。在实施例中,字段可以保持基本类型、对象或数组。当字段保持基本类型时,描述符是识别该基本类型的字符串(例如,“B”=byte、“C”=char、“D”=double、“F”=float、“I”=int、“J”=long int等)。当字段保持对象时,描述符是识别该对象的类名称的字符串(例如,“LClassName”)。在这种情况下,“L”指示引用,因此“L ClassName”表示对类ClassName的对象的引用。当字段是数组时,描述符识别由该数组保持的类型。例如,“[B”指示字节的数组,其中“[”指示数组并且“B”指示数组保持基本字节类型。但是,由于数组可以嵌套,因此数组的描述符也可以指示嵌套。例如,“[[L ClassName”指示如下数组,其中每个索引对保持类ClassName的对象的数组进行保持。在一些实施例中,ClassName是完全限定的,并且包括该类的简单名称以及该类的路径名。例如,ClassName可以指示文件被存储在包、库或托管该类文件200的文件系统中的什么位置。
在方法的情况下,描述符识别方法的参数和方法的返回类型。例如,方法描述符可以遵循一般形式“({ParameterDescriptor})ReturnDescriptor”,其中{ParameterDescriptor}是表示参数的字段描述符的列表,并且ReturnDescriptor是识别返回类型的字段描述符。例如,字符串“V”可以被用于表示void返回类型。因此,在源代码文件101中定义为“Object m(int I,doubled,Thread t){...}”的方法与描述符“(IDLThread)L Object”相匹配。
在实施例中,保持在方法结构209中的虚拟机指令包括对常量表201的条目进行引用的操作。使用Java作为示例,考虑以下类:
在以上示例中,Java方法add12and13在类A中定义,不带参数,并且返回整数(integer)。方法add12and13的主体调用类B的静态方法addTwo,该静态方法采用常整数值12和13作为参数,并且返回结果。因此,在常量表201中,编译器102除其它条目之外还包括与对方法B.addTwo的调用对应的方法引用结构。在Java中,对方法的调用向下编译为JVM的字节码中的invoke命令(在这种情况下为invokestatic,因为addTwo是类B的静态方法)。该invoke命令被提供常量表201中与方法引用结构对应的索引,该方法引用结构识别定义addTwo“B”的类、addTwo的名称“addTwo”、以及addTwo的描述符“(I I)I”。例如,假设上述方法引用被存储在索引4处,则字节码指令可以表现为“invokestatic#4”。
由于常量表201使用携带识别信息的结构来符号地引用类、方法和字段而不是直接引用存储器位置,因此常量表201的条目被称为“符号引用”。符号引用被用于类文件103的一个原因是因为在一些实施例中一旦类被加载到运行时环境113中,编译器102就不知道类将如何被存储以及存储在哪里。如将在2.3部分中所描述的,在所引用的类(及相关联的结构)已被加载到运行时环境中并且被分配具体的存储器位置之后,符号引用的运行时表示会最终地被虚拟机104解析为实际的存储器地址。
2.2示例虚拟机架构
图3图示了根据实施例的以框图形式的示例虚拟机存储器布局300。为了提供清楚的示例,其余的讨论将假设虚拟机104遵循图3中绘出的虚拟机存储器布局300。此外,虽然虚拟机存储器布局300的组件可以被称为存储器“区域”,但是不要求存储器区域是连续的。
在图3图示的示例中,虚拟机存储器布局300被划分为共享区域301和线程区域307。共享区域301表示在虚拟机104上执行的各种线程之间共享的结构被存储其中的存储器中的区域。共享区域301包括堆302和按类(per-class)区域303。在实施例中,堆302表示从中分配用于类实例和数组的存储器的运行时数据区域。在实施例中,按类区域303表示在其中存储与单个类有关的数据的存储区域。在实施例中,对于每个加载的类,按类区域303包括:表示来自该类的常量表201的数据的运行时常量池304、字段和方法数据306(例如,以保持该类的静态字段)、以及表示用于该类的方法的虚拟机指令的方法代码305。
线程区域307表示存储特定于各个线程的结构的存储器区域。在图3中,线程区域307包括线程结构308和线程结构311,其表示由不同线程利用的按线程(per-thread)结构。为了提供清楚的示例,图3中绘出的线程区域307假设两个线程正在虚拟机104上执行。但是,在实际环境中,虚拟机104可以执行任何任意数量的线程,其中线程结构的数量相应地缩放。
在实施例中,线程结构308包括程序计数器309和虚拟机栈310。类似地,线程结构311包括程序计数器312和虚拟机栈313。在实施例中,程序计数器309和程序计数器312存储正由它们的相应的线程执行的虚拟机指令的当前地址。
因此,当线程逐步通过指令时,程序计数器被更新以维持指向当前指令的索引。在实施例中,虚拟机栈310和虚拟机栈313各自存储用于其相应线程的帧(frame),该帧保持局部变量和部分结果并且还被用于方法调用和返回。
在实施例中,帧是被用于存储数据和部分结果、返回方法的值、以及执行动态链接的数据结构。每次调用方法时创建新帧。当使得生成帧的方法完成时,该帧被销毁。因此,当线程执行方法调用时,虚拟机104生成新帧并将该帧推送到与该线程相关联的虚拟机栈上。
当方法调用完成时,虚拟机104将方法调用的结果传递回到前一帧,并将当前帧从栈中弹出。在实施例中,对于给定的线程,在任何点处一个帧是活动的。此活动帧被称为当前帧,使得生成当前帧的方法被称为当前方法,并且当前方法所属的类被称为当前类。
图4图示了根据实施例的以框图形式的示例帧400。为了提供清楚的示例,其余的讨论将假设虚拟机栈310和虚拟机栈313的帧遵守帧400的结构。
在实施例中,帧400包括局部变量401、操作数栈402和运行时常量池引用表403。在实施例中,局部变量401被表示为变量数组,每个变量保持一值,例如,Boolean、byte、char、short、int、float或reference值。此外,一些值类型(诸如long或double)可以由数组中的多于一个的条目表示。局部变量401被用于在方法调用上传递参数并存储部分结果。例如,当响应于调用方法而生成帧400时,参数可以被存储在局部变量401内的预定义位置中,诸如与该调用中的第一至第N个参数对应的索引1-N。
在实施例中,当虚拟机104创建帧400时,操作数栈402默认为空。然后,虚拟机104从当前方法的方法代码305中供给指令以将来自局部变量401的常量或值加载到操作数栈402上。其它指令从操作数栈402获取操作数、对其进行操作、并将结果推送回到操作数栈402上。此外,操作数栈402被用于准备要传递给方法的参数和接收方法结果。例如,正被调用的方法的参数可以在向方法发出调用之前被推送到操作数栈402上。然后,虚拟机104为该方法调用生成新帧,其中前一帧的操作数栈402上的操作数被弹出并被加载到该新帧的局部变量401中。当被调用的方法终止时,新帧从虚拟机栈中弹出并且返回值被推送到前一帧的操作数栈402上。
在实施例中,运行时常量池引用表403包含对当前类的运行时常量池304的引用。运行时常量池引用表403被用于支持解析。解析是将常量池304中的符号引用转换成具体的存储器地址的处理,从而根据需要加载类以解析尚未定义的符号并将变量访问转换成与这些变量的运行时位置相关联的存储结构中的适当偏移量。
2.3加载、链接和初始化
在实施例中,虚拟机104动态地加载、链接和初始化类。加载是找到具有特定名称的类并在运行时环境113的存储器内从该类的相关联类文件200创建表示的处理。例如,在虚拟机存储器布局300的按类区域303内为该类创建运行时常量池304、方法代码305以及字段和方法数据306。链接是取得类的内存表示并将其与虚拟机104的运行时状态组合使得该类的方法可以被执行的处理。初始化是执行类构造函数(constructor)以设置类的字段和方法数据306的开始状态和/或在堆302上创建用于经初始化的类的类实例的处理。
以下是可以由虚拟机104实现的加载、链接和初始化技术的示例。但是,在许多实施例中,这些步骤可以被交错,使得初始类被加载,然后在链接期间,第二个类被加载以解析在第一个类中找到的符号引用,这又导致第三个类被加载,等等。因此,经历加载、链接和初始化阶段的进度可以因类而异。此外,一些实施例可以延迟(“懒惰”执行)加载、链接和初始化处理的一个或多个功能,直到实际上需要该类。例如,对方法引用的解析可以被延迟,直到调用该方法的虚拟机指令被执行。因此,对于每个类,执行步骤的确切时间在各种实现方式之间会有很大不同。
为了开始加载处理,虚拟机104通过调用加载初始类的类加载器107来启动。指定初始类的技术将在实施例之间不同。例如,一种技术可以使虚拟机104在启动时接受指定初始类的命令行参数。
为了加载类,类加载器107解析与该类对应的类文件200,并且确定类文件200是否是良好构造的(满足虚拟机104的句法期望)。如果不是,则类加载器107生成错误。例如,在Java中,错误可能以异常的形式生成,其中异常被抛出给异常处理器进行处理。否则,类加载器107通过在按类区域303内为该类分配运行时常量池304、方法代码305以及字段和方法数据306来生成该类的内存表示。
在一些实施例中,当类加载器107加载类时,类加载器107还递归加载该被加载类的超类。例如,虚拟机104可以确保在继续特定类的加载、链接和初始化处理之前,该特定类的超类被加载、链接和/或初始化。
在链接期间,虚拟机104验证类、准备类、并且执行在类的运行时常量池304中定义的符号引用的解析。
为了验证类,虚拟机104检查类的内存表示是否在结构上正确。例如,虚拟机104可以检查除通用类Object之外的每个类具有超类、检查最终类没有子类以及最终方法没有被覆盖、检查常量池条目是否彼此一致、检查当前类是否具有对常量池304中引用的类/字段/结构的正确访问权限、检查方法的虚拟机104代码将不会引起意外行为(例如,确保跳转指令不会将虚拟机104发送到超出该方法的结束范围),等等。在验证期间执行的确切检查取决于虚拟机104的实现方式。在一些情况下,验证会导致附加的类被加载,但不一定要求那些类在继续之前也被链接。例如,假设类A包含对类B的静态字段的引用。在验证期间,虚拟机104可以检查类B,以确保被引用的静态字段实际上存在,这可能导致类B的加载,但不一定导致类B的链接或初始化。但是,在一些实施例中,某些验证检查可以被一直延迟到以后的阶段,诸如在符号引用的解析期间被检查。例如,一些实施例可以延迟检查对符号引用的访问许可,直到这些引用被解析。
为了准备类,虚拟机104将位于类的字段和方法数据306内的静态字段初始化为默认值。在某些情况下,将静态字段设置为默认值可能与运行该类的构造函数不同。例如,验证处理可以将静态字段清零或将其设置为构造函数期望这些字段在初始化期间具有的值。
在解析期间,虚拟机104从包括在类的运行时常量池304中的符号引用当中动态地确定具体的存储器地址。为了解析符号引用,虚拟机104利用类加载器107加载在符号引用中识别出的类(如果尚未加载)。一旦被加载,虚拟机104就知道所引用类及其字段/方法在按类区域303内的存储器位置。然后,虚拟机104用对所引用类、字段或方法的具体存储器位置的引用来替换符号引用。在实施例中,虚拟机104将解析进行高速缓存,以在当虚拟机104处理另一个类时遇到相同类/名称/描述符的情况下进行重用。例如,在一些情况下,类A和类B可能调用类C的同一方法。因此,当对类A执行解析时,该结果可以被高速缓存,并且在解析类B中的相同符号引用期间被重用,以减少开销。
在一些实施例中,在链接期间解析符号引用的步骤是可选的。例如,实施例可以以“懒惰”的方式执行符号解析,从而将解析的步骤延迟直到需要所引用的类/方法/字段的虚拟机指令被执行。
在初始化期间,虚拟机104执行类的构造函数以设置该类的开始状态。例如,初始化可以初始化类的字段和方法数据306并且在堆302上生成/初始化由构造函数创建的任何类实例。例如,用于类的类文件200可以指定特定方法是用于设置开始状态的构造函数。因此,在初始化期间,虚拟机104执行该构造函数的指令。
在一些实施例中,虚拟机104通过初始地检查字段/方法是否在所引用的类中被定义来执行对字段和方法引用的解析。否则,虚拟机104针对所引用的字段/方法递归地搜索所引用的类的超类,直到定位该字段/方法或者到达顶级超类(在这种情况下生成错误)。
3.垃圾收集
图5图示了根据实施例的虚拟机的执行引擎和堆存储器。如图5中所示,系统500包括执行引擎502和堆530。系统500可以包括比图5中所示的组件更多或更少的组件。图5中所示的组件可以彼此在本地或远离。
在一个或多个实施例中,堆530表示运行时数据区域,从该运行时数据区域中分配用于类实例和数组的存储器。堆530的示例在上面被描述为图3中的堆302。
堆530存储在应用执行期间创建的对象534a-534d。存储在堆530中的对象可以是普通对象、对象数组或另一类型的对象。普通对象是类实例。类实例是由类实例创建表达式显式地创建的。对象数组是容器对象,它保持固定数量的单一类型的值。对象数组是特定的一组普通对象。
堆530存储存活对象534b、534d(由虚线图案指示)和不使用的对象534a、534c(也称为“死对象”,由空白图案指示)。不使用的对象是不再被任何应用使用的对象。存活对象是仍在被至少一个应用使用的对象。如果对象(a)被根引用指向或(b)可从由根引用所指向的另一个对象追踪,那么该对象仍在被应用使用。如果对第一对象的引用被包含在第二对象中,那么第一对象从第二对象“可追踪”。
样本代码可以包括以下内容:
/>
执行上述样本代码的应用线程508a在堆530中创建对象temp。对象temp是Person类型,并且包括两个字段。由于字段age是整数,堆530的分配给temp的部分直接存储字段age的值“3”。由于字段name是字符串,因此堆530的分配给temp的部分不直接存储name字段的值;而是堆530的分配给temp的部分存储对另一个String类型对象的引用。该String对象存储值“Sean”。该String对象被称为从Person对象“可追踪”。
在一个或多个实施例中,执行引擎502包括被配置为执行各种操作的一个或多个线程。如图所示,例如,执行引擎502包括垃圾收集(GC)线程506a-b和应用线程508a-b。
在一个或多个实施例中,应用线程508a-b被配置为执行一个或多个应用的操作。应用线程508a-b在运行时期间创建对象,这些对象存储在堆530上。应用线程508a-b也可以被称为“突变(mutator)”,因为应用线程508a-b可以使堆530突变(在GC周期的并发阶段期间和/或在GC周期之间)。
在一个或多个实施例中,GC线程506a-b被配置为执行垃圾收集。GC线程506a-b可以基于调度和/或事件触发器(诸如当达到堆(或其区域(region))的阈值分配时)迭代地执行GC周期。GC周期包括一组GC操作,这些操作用于回收堆中被不使用的对象所占用的存储器位置。
在实施例中,多个GC线程506a-b可以并行地执行GC操作。并行工作的该多个GC线程506a-b可以被称为“并行收集器”。
在实施例中,GC线程506a-b可以与应用线程508a-b的执行并发地执行至少一些GC操作。与应用线程508a-b并发操作的GC线程506a-b可以被称为“并发收集器”或“部分并发收集器”。
在实施例中,GC线程506a-b可以执行分代垃圾收集。堆被分成不同的区域。第一区域(可以被称为“年轻代空间”)存储尚未满足从第一区域提升到第二区域的标准的对象;第二区域(可以被称为“老年代空间”)存储已满足从第一区域提升到第二区域的标准的对象。例如,当存活对象生存至少阈值数量的GC周期时,该存活对象就从年轻代空间提升到老年代空间。
用于执行垃圾收集的各种不同的GC处理实现不同的存储器效率、时间效率和/或资源效率。在实施例中,可以针对不同的堆区域执行不同的GC处理。作为示例,堆可以包括年轻代空间和老年代空间。可以对年轻代空间执行一种类型的GC处理。可以为老年代空间执行不同类型的GC处理。下面描述了不同GC处理的示例。
作为第一示例,复制收集器(copying collector)涉及堆的至少两个单独定义的地址空间,称为“源空间(from-space)”和“目标空间(to-space)”。复制收集器识别存储在被定义为源空间的区域内的存活对象。复制收集器将存活对象复制到被定义为目标空间的另一个区域。在识别并复制所有存活对象之后,定义为源空间的区域被回收。新的存储器分配可以从原始源空间的第一个位置开始。
复制可以在堆内至少三个不同的区域完成:一个伊甸园空间(Eden space)以及两个生存者空间(survivor space)S1和S2。对象最初分配在伊甸园空间中。当伊甸园空间已满时,会触发GC周期。存活对象从伊甸园空间被复制到生存者空间之一,例如S1。在下一个GC周期,伊甸园空间中的存活对象被复制到另一个生存者空间,这将是S2。此外,S1中的存活对象也被复制到S2。
作为另一个示例,标记和清扫(mark-and-sweep)收集器将GC操作分为至少两个阶段:标记阶段和清扫阶段。在标记阶段期间,标记和清扫收集器用“存活”位标记每个存活对象。例如,该存活位可以是存活对象的对象标头内的位。在清扫阶段期间,标记和清扫收集器遍历堆以识别连续存储器地址空间的所有未标记块。标记和清扫收集器将未标记的块链接在一起,形成有组织的空闲列表。这些未标记的块被回收。使用这些空闲列表来执行新的存储器分配。新对象可以被存储在从空闲列表中识别出的存储器块中。
标记和清扫收集器可以被实现为并行收集器。附加地或替代地,标记和清扫收集器可以被实现为并发收集器。并发标记和清扫收集器的GC周期内的示例阶段包括:
阶段1:识别根引用所引用的对象(这与正在执行的应用不是并发的)
阶段2:标记从根引用所引用的对象可到达的对象(这可以是并发的)
阶段3:识别在阶段2期间已作为程序执行的一部分被修改的对象(这可以是并发的)
阶段4:重新标记在阶段3识别出的对象(这不是并发的)
阶段5:清扫堆以获得空闲列表并回收存储器(这可以是并发的)
作为另一个示例,压缩收集器尝试对回收的存储器区域进行压缩。堆被分区为一组大小相等的堆区域,每个区域是虚拟存储器的连续范围。压缩收集器执行并发的全局标记阶段以确定整个堆中对象的存活度(liveness)。在标记阶段完成之后,压缩收集器识别大部分为空的区域。压缩收集器首先收集这些区域,这通常会产生大量的空闲空间。压缩收集器将其收集和压缩活动集中在堆中的可能充满可回收对象(即垃圾)的区域。压缩收集器将存活对象从堆的一个或多个区域复制到堆上的单个区域,并在该处理中压缩和释放存储器。这种清除(evacuation)可以在多处理器上并行执行,以减少暂停时间并增加吞吐量。
并发压缩收集器的GC周期内的示例阶段包括:
阶段1:识别根引用所引用的对象(这与正在执行的应用不并发)
阶段2:标记从根引用所引用的对象可到达的对象(这可以是并发的)
阶段3:识别在阶段2期间已作为程序执行的一部分被修改的对象(这可以是并发的)
阶段4:重新标记在阶段3处识别出的对象(这不是并发的)
阶段5:将存活对象从源区域复制到目的地区域,从而回收源区域的存储器空间(这不是并发的)
作为另一个示例,加载屏障收集器标记并压缩存活对象,但懒惰地对指向重定位对象的引用进行重新映射。加载屏障收集器依赖于嵌入被存储在堆上的引用内的“颜色”。颜色表示GC状态,并跟踪相对于引用的GC操作的进度。颜色是通过存储在引用的某些位内的元数据捕获的。
在时间的每时每刻,所有GC线程506a-b就什么颜色是“良好颜色”或“良好GC状态”达成一致。将引用从堆530加载到调用栈的GC线程506a-b首先应用检查以确定该引用的当前颜色是否良好。类似地,将引用从堆530加载到调用栈的应用线程508a-b首先应用检查以确定该引用的当前颜色是否良好。该检查可以被称为“加载屏障”。颜色良好的引用将命中快速路径,快速路径不会产生附加工作。否则,该引用将命中慢速路径。慢速路径涉及某些GC操作,这些操作将引用从当前GC状态带入良好GC状态。该引用在堆530中所驻留的槽(slot)被更新为带有颜色良好的别名(good-colored alias),以避免随后命中慢速路径(更新为良好颜色也可以被称为“自我修复”)。
例如,陈旧的引用(对在压缩期间已并发移动的对象的引用,这意味着地址可能指向该对象的过时副本,或另一个对象,或者甚至什么也没有)保证没有良好颜色。尝试从堆加载该引用的应用线程首先执行加载屏障。通过加载屏障,引用被识别为陈旧(不是良好颜色)。该引用因此被更新为指向对象的新位置并且与良好颜色相关联。具有经更新的地址和良好颜色的引用被存储到堆中。具有经更新的地址的引用也可以被返回给应用线程。但是,返回给应用线程的引用不一定包含任何颜色。
可以使用与上述那些GC处理不同的附加和/或替代类型的GC处理。其它类型的GC处理也可能依赖于引用的“颜色”,或者与存储在引用内的垃圾收集相关的元数据。
在实施例中,颜色与堆引用一起存储,但不与可解除引用的引用一起存储。术语“堆引用”是指存储在堆530上的引用。术语“可解除引用的引用”是指执行引擎用来访问该引用所指向的对象的值的引用。获得引用所指向的对象的值被称为对该引用“解除引用”。尝试对存储在堆530上的引用解除引用的GC线程506a-b首先将该引用从堆530加载到GC线程506a-b的调用栈。尝试对存储在堆530上的引用解除引用的应用线程508a-b首先将该引用从堆530加载到应用线程508a-b的调用栈。(例如,应用线程将引用加载到调用栈的帧400内的局部变量401中,如上文参考图4所述)。堆引用和/或可解除引用的引用在本文中被一般地称为“引用”。
参考图6,图6图示了根据实施例的堆引用和可解除引用的引用。引用可以包括任意数量的位,这取决于计算环境。例如,在Intel x86-64机器中,引用有64位。
在实施例中,可解除引用的引用600包括不可寻址部分602和可寻址部分604。可寻址部分604定义该引用600可以到达的最大地址空间。取决于应用在其上执行的硬件系统,不可寻址部分602可能被要求在引用600被解除引用之前遵守规范形式。如果施加了这样的要求,那么硬件系统(诸如处理器)在尝试对不兼容的可解除引用的引用解除引用时会生成错误。因此,引用600的不可寻址部分602不能被用于存储任何与GC相关的元数据,诸如GC状态。例如,在Intel x86-64机器中,引用的可寻址部分有48位,不可寻址部分有16位。基于硬件施加的限制,该引用最多可以到达248个唯一地址。规范形式要求不可寻址部分是存储在可寻址部分中的值的符号扩展610(即,高阶的位48至63必须是存储在位47中的值的副本)。
如图所示,可寻址部分604包括地址606和可选的其它位608。地址606是指该引用600所指向的对象的地址。其它位608可以是未使用的。替代地,其它位608可存储元数据,其可能但不一定与垃圾收集相关。
如上所述,可解除引用的引用600包括存储在调用栈上的引用。附加地或替代地,可解除引用的引用600包括嵌入在存储在代码高速缓存和/或其它存储器位置上的已编译方法内的引用。已编译方法是已从高级语言(诸如字节码)转换成低级语言(诸如机器码)的方法。应用线程可以直接访问代码高速缓存或其它存储器位置内的已编译方法,以执行该已编译方法。作为示例,已编译方法可以由图1的JIT编译器109生成。作为另一个示例,已编译方法可以由虚拟机的另一个组件生成。
在实施例中,堆引用650包括瞬态颜色位652、地址位606和可选的其它位608。瞬态颜色652表示跟踪相对于引用650的GC操作的进度的GC状态。颜色652是“瞬态的”,因为当引用从堆530加载到调用栈时,颜色652不需要与该引用保持在一起。其它位608可以是未使用的。替代地,其它位608可以存储元数据,这些元数据可以但不一定与垃圾收集相关。在实施例中,瞬态颜色652被存储在堆引用650的最低(最右)位中。例如,瞬态颜色652的长度可以是两个字节,并且被存储在堆引用650的位0-15中。
在实施例中,瞬态颜色652包括一个或多个重新映射位654。在实施例中,重新映射位654为GC的每一代提供GC中该代的当前重定位阶段的指示。在实施例中,GC包括两代(例如,年轻代和老年代),并且重新映射位包括足以描述年轻代和老年代两者的当前重定位阶段的位数。例如,重新映射位可以包括4位。在实施例中,重新映射位654被存储在瞬态颜色652的最高部分中。例如,在瞬态颜色652被存储在堆引用650的位0-15中的情况下,重新映射位654可以构成堆引用654的位12-15。
瞬态颜色652可以可选地包括附加颜色位,包括一个或多个标记位656、一个或多个记忆集(remembered set)位658、以及一个或多个其它位660。在实施例中,重新映射位654可以表示GC的重定位阶段。在多代GC中,重新映射位654可以表示GC的每一代的重定位阶段。下面将更详细地描述重新映射位。
在实施例中,标记位656可以表示GC的标记奇偶校验。在多代GC中,标记位656可以包括GC的每个代的标记奇偶校验的表示。例如,在包括年轻代和老年代的GC中,标记位656可以包括用于表示年轻代中的标记奇偶校验的两个位和用于表示老年代中的标记奇偶校验的两个位。
在实施例中,记忆集位658可以表示GC的记忆集阶段。作为特定示例,记忆集位可以是两个位,其中设置的单个位表示记忆集的阶段。记忆集位指示从老年代到年轻代中的潜在引用。
在实施例中,其它位660可以用于表示GC状态的其它特征。替代地,可以不使用其它位660。在一些实施例中,可以确定其它位660的数量,使得瞬态颜色652中的位的数量是字节的整数(例如,位的数量可被8整除)。例如,瞬态颜色652中的位的数量可以是8位或16位。在又一个实施例中,瞬态颜色652可以总共表示一组不同的GC状态。瞬态颜色652可以表示在附加和/或替代类型的GC处理中使用的GC状态。
在实施例中,瞬态颜色652表示一组GC状态,而其它位608表示另一组GC状态。作为示例,其它位608可以跟踪引用的年龄(例如,该引用已经经历的GC周期的数量)。
在实施例中,GC周期可以包括多个阶段。在一些实施例中,GC系统可以包括针对堆中指定的每一代的单独的GC周期。例如,GC系统可以包括年轻代周期和老年代周期。年轻代GC周期可以包括以下阶段:标记开始、并发标记、重定位开始、并发重定位。在一些实施例中,老年代GC周期与年轻代GC周期对称,并且可以包括相同的阶段。在一些实施例中,每个阶段并发执行,这意味着一个或多个应用线程508a、508b可以在该阶段期间继续执行。在其它实施例中,阶段中的一个或多个阶段(例如,标记开始、重定位开始)可以是非并发的。全部应用线程508a-b必须在非并发阶段期间暂停(也称为“停止世界暂停”或“STW暂停”)。在一些实施例中,当分配给特定代的堆上的对象超过存储阈值时,或者在经过特定时间段而没有GC周期之后,GC周期(例如,年轻代GC周期或老年代GC周期)开始。
以下是各阶段的详细讨论。也可以在每个阶段中执行除了下面讨论的操作之外的附加和/或替代操作。
标记开始:在标记开始阶段,GC通过更新年轻代的标记奇偶校验和/或记忆集奇偶校验来更新一个或多个常量(例如,“良好颜色”)。在标记开始期间,GC可以捕获记忆集数据结构的快照。
并发标记:GC线程506a-b执行对象图的遍历以识别和标记所有存活对象。GC线程通过堆530的传递闭包进行追踪,从而截断在年轻代之外进行的任何遍历。如果在此处理期间在堆530中发现陈旧引用,那么用该引用所引用的对象的当前地址来更新该引用。堆530中的该引用也被更新以指示良好颜色。
可选地,记录每页存活度信息(每个存储器页上存活对象的总数和总大小)。存活度信息可以用于选择供清除的页面。
标记结束:GC线程506a-b标记任何排队的对象并追踪排队的对象的传递闭包,并确认标记完成。
重定位开始:在重定位开始期间,GC通过至少更新重新映射位来更新一个或多个常量(例如,“良好颜色”)。在实施例中,GC线程506a-b选择空区域作为目标空间。在另一个实施例中,可以使用附加和/或替代方法来为重定位的对象选择目标空间。
并发重定位:标记的源空间对象可以重定位到所选择的目标空间(在特定情况下可能使用就地压缩)。每个被移动并包含指向当前进行重定位的年轻代的陈旧指针的对象都被添加到记忆集中。这有助于确保指针随后被重新映射。
4.加载屏障和写屏障
在一个或多个实施例中,GC周期包括一个或多个并发阶段。在并发阶段期间,一个或多个应用线程可以与一个或多个GC线程并发执行。当应用线程尝试将引用从堆加载到调用栈时,应用线程可以执行引用加载屏障。当应用线程尝试将引用写入到堆上时,应用线程可以执行引用写屏障。
图7图示了根据实施例的引用加载屏障。如图所示,堆730包括地址00000008、00000016、……、00000048、00000049、00000050。调用栈局部变量732包括寄存器r1、r2、r3。在示例中,引用包括32位。堆引用的颜色可以由位0-15指示。例如,颜色可以包括4个重新映射位(例如,位12-15),用于指示年轻代和老年代的重定位阶段;4个标记位(例如,位8-11),用于指示年轻代和老年代中的标记奇偶校验;两个记忆集位(例如,位6-7),用于指示GC中的记忆集奇偶校验;以及六个其它位(位0-5),其可以不使用或者可以存储其它元数据。
关于重新映射位,这些位可以使用这样的编码,使得四个重新映射位当中的恰好一个位被设置,其中被设置的一个位指示老年代和年轻代两者的重定位阶段。特别地,四个重新映射位可以表示为四数位(four-digit)的二进制数。对于重新映射位,值0001可以指示老年代重定位处于偶数阶段,并且年轻代重定位处于偶数阶段;值0010可以指示老年代重定位处于偶数阶段,并且年轻代重定位处于奇数阶段;值0100可以指示老年代重定位处于奇数阶段,并且年轻代重定位处于偶数阶段;值1000可以指示老年代重定位处于奇数阶段,并且年轻代重定位处于奇数阶段。因此,恰好包括一个设置位的四个可能值表示老年代和年轻代内的重定位阶段的每一种可能的组合。
GC还可以设置比重新映射位当中以当前良好颜色设置的特定位的位置高1的移位值。这确保了该特定位是从地址移位出的最后一位。例如,假设重新映射位是位12-15,那么移位值可以被设置为13和16之间的值,其中值13对应于位12为重新映射位的设置位,值14对应于位13为重新映射位的设置位,值15对应于位14为重新映射位的设置位,并且值16对应于位15为重新映射位的设置位。在实施例中,移位值至少在每个新的GC重定位阶段开始时改变,并且可以使用例如已编译方法进入屏障修补(compiled method entry barrierpatching)来设置。
在实施例中,引用的地址部分可以与颜色位重叠,紧接着重新映射位的设置位之后开始。因此,引用的地址部分可以从位13和位16之间的任何地方开始,这取决于设置位在重新映射位中的位置。但是,重叠内包含的任何位都被设置为零。因此,该方法要求每个地址的三个最低位为零。
样本代码可以包括以下内容:
基于代码行Person temp1=new Person(),应用线程在堆730中创建新对象,并且引用temp1引用该新对象。(由temp1引用的)该对象属于Person类型,并包含String类型的name字段。(由temp1引用的)该对象被存储在堆730内的地址“00000008”处。(由temp1引用的)该对象的name字段被存储在堆730内的地址“00000016”处。name字段用引用705填充。引用705包括颜色706并指向地址“0042”。因此,地址“00000048”包含(由temp1引用的)对象的name的值,并且该值为“TOM”。
基于代码行String temp2=temp1.name,应用线程尝试加载由temp1引用的对象的name字段中的引用705。应用线程命中引用加载屏障710。引用加载屏障710包括用于检查引用705的颜色706是否包括与年轻代和老年代两者的当前重定位阶段相匹配的重新映射位的指令。特别地,该指令确定是否设置了重新映射位当中的正确位。
为了实现这一点,对引用705应用了逻辑按位右移操作。系统可以将引用向右移动n次,其中n等于由GC设置的移位值。每个位被右移n个位置,并且具有默认值的n位被插入到最左(例如,最高)位中。例如,如果规范形式要求最高位为0,那么移位操作可以将n个0插入到最左的位中。因为颜色706被存储在引用705的最低(最右)位中,因此应用于引用的右移操作具有移除颜色位706的效果。此外,因为重新映射位被存储在颜色的最高位部分,因此重新映射位是通过右移操作移除的最后一位或多位。特别地,由GC设置的移位值对应于重新映射位中的在当前“良好颜色”中设置的恰好一位的位置。
然后系统可以确定从引用移位出的最后一位是否被设置了(例如,指示重新映射位的正确位被设置)。例如,在x86-64架构中,系统可以确定是否设置了进位标志和零标志。在按位右移操作之后,进位标志等于从引用移位出的最后一位,并且如果移位操作完成之后,引用中的所有位都为0,那么零标志被设置。因此,当重新映射位中的正确位被设置时,进位标志被设置;当引用是对空值(例如,地址0)的引用时,零标志被设置。如果未设置进位标志且未设置零标志,那么应用线程采用慢速路径714。在其它情况下(例如,设置了进位标志,或者设置了零标志),应用线程采用快速路径712。
快速路径712不一定涉及任何GC操作,诸如重新映射引用和/或将对象标记为存活。颜色706已通过右移操作从引用705中移除。结果“00000048”作为引用707被保存在调用栈局部变量732中,诸如在r3处。然后,应用线程可以解除对引用707的引用。应用线程访问由引用707指示的地址,即堆730内的地址“00000048”。应用线程在堆730内的地址“00000048”处获得值“TOM”。
当系统确定应用线程应当采用慢速路径时,应用线程可以选择慢速路径池中的一个。特别地,应用线程可以重新加载引用并基于颜色706从慢速路径池中选择慢速路径。例如,应用线程可以重新映射由引用705指示的地址。例如,应用可以将引用705所指向的对象标记为存活。然后应用线程可以将引用705的颜色706更新为良好颜色。另外,应用线程可以从引用705中移除颜色706以存储在调用栈局部变量732中,如上所述。特别地,应用线程可以对引用705应用逻辑按位右移操作。系统可以将引用向右移位n次,其中n等于由GC设置的移位值。
图8图示了根据实施例的引用写屏障。如图所示,堆830包括地址00000008、00000016、……00000024、00000032、……00000048。调用栈局部变量832包括寄存器r1、r2、r3。在示例中,引用包括32位。堆引用的颜色可以由位0-15指示。
样本代码可以包括以下内容:
基于代码行Person temp2=new Person(),应用线程在堆830中创建新对象,并且引用temp2引用该新对象。(由temp2引用的)该对象属于Person类型,并包含String类型的name字段。(由temp2引用的)该对象被存储在堆830内的地址“00000024”处。(由temp2引用的)该对象的name字段被存储在堆830内的地址“00000032”处。name字段用引用805填充。
基于代码行temp2.name=temp3,应用线程尝试将引用807从调用栈局部变量832写入到堆830中。特别地,应用线程尝试将引用807写入到地址“00000032”,该地址是存储temp2所引用的对象的name字段的位置。
应用线程命中引用写屏障810。特别地,应用线程基于当前GC阶段来确定当前哪种颜色是良好颜色。引用写屏障810包括用于确定要修改的引用805的颜色806的至少一部分是否是“良好”颜色的指令。写屏障使得应用线程至少将存储在引用805的颜色806中的标记奇偶校验的指示与由GC(例如,通过确定的当前良好颜色)指示的当前标记奇偶校验进行比较。在一些实施例中,写屏障还使得比较附加GC状态,包括将由颜色806指示的记忆集奇偶校验和由GC(例如,通过确定的当前良好颜色)指定的当前记忆集奇偶校验进行比较。在一些情况下,写屏障可以确定颜色806的整体是否与由GC指定的“良好”颜色相匹配。作为特定示例,写屏障可以使得应用线程执行按位比较操作,以将来自引用的特定数量的位(例如,字节、字)与由GC存储为常量的良好颜色进行比较。在其它实施例中,写屏障可以使得应用线程对引用805的颜色806以及由GC指定的“良好”颜色的按位补码执行测试指令。
如果写屏障确定引用805的颜色806的测试部分与由GC指定的良好颜色不匹配,那么写屏障可以使得应用将引用805写入到数据结构。该数据结构可以是例如链表。引用可以排队供GC分析。特别地,作为标记处理的一部分,GC可以遍历数据结构中的引用。
如果写屏障确定引用805的颜色806的测试部分与由GC指定的良好颜色相匹配。写屏障可以使得系统避免将引用添加到数据结构。
写屏障还可以使得应用线程用良好颜色为引用807着色。使用良好颜色为引用807着色可以包括:(a)对引用应用按位左移操作以将引用向左移位n次,其中n等于由GC设置的移位值并在引用的最低位中插入n个0,以及(b)对左移位结果和良好颜色位掩码应用逻辑按位OR,该良好颜色位掩码包括由GC在最低位(例如,位0-15)中设置的良好颜色和每个其它位中的0。OR的结果是“00488A40”。应用线程将结果“00488A40”写入到堆830中的地址“00000032”。
6.用于写入堆引用以改进开始时快照垃圾收集标记处理的写屏障
图9图示了根据实施例的当通过应用线程写入堆引用时使用写屏障来改进开始时快照(SATB)GC标记处理的一组操作。图9中所示的一个或多个操作可以一起被修改、重新布置或省略。因此,图9中所示的特定操作顺序不应被解释为限制一个或多个实施例的范围。如图9中所示的操作不限制操作在一组代码中的表达方式。图9的多个操作可以对应于一组代码中的单个指令;相反,图9的单个操作可以对应于一组代码中的多个指令。图9的操作被描述为由单个应用线程执行;但是,这些操作可以由多个应用线程和/或GC线程执行。
GC可以发起用于将存储在堆的至少一部分中的对象标记为存活的标记处理的执行。标记处理可以标记例如存储在堆的年轻代部分中的对象、存储在堆的老年代部分中的对象、或者存储在堆的任何部分中的对象。在标记处理开始时,GC可以为GC指定当前“良好”颜色。特别地,“良好”颜色可以至少对标记奇偶校验进行改变。在GC标记整个堆的情况下,GC可能会改变老年代和年轻代两者的标记奇偶校验。在GC正在标记存储在堆的年轻代部分中的对象的情况下,GC可以更新年轻代的标记奇偶校验。在GC正在标记存储在堆的老年代部分中的对象的情况下,GC可以更新老年代的标记奇偶校验。在实施例中,GC可以使用例如已编译方法进入屏障修补将当前“良好”颜色存储为应用线程可访问的一个或多个常量。
在标记处理的执行期间,一个或多个实施例包括由突变(应用)线程接收用于将引用写入到堆存储器上的请求(操作902)。应用线程执行一组代码(例如,字节码)。该组代码包括用于将引用写入到堆存储器上的请求。例如,该请求可以是将存储在应用线程的调用栈上的引用写入到堆存储器上。在实施例中,该请求可以是用新值覆写当前存储在特定地址处的值。
响应于接收到该请求,写屏障可以使应用线程至少确定垃圾收集标记处理正在遍历的多个对象的标记奇偶校验(操作904)。在实施例中,应用线程可以确定更多信息。例如,应用线程可以确定GC的所有代的标记奇偶校验。应用线程可以确定附加的GC状态信息,诸如记忆集奇偶校验。在实施例中,应用线程可以确定GC的当前“良好”颜色。在实施例中,该确定包括GC将该值存储到可由应用线程访问的常量。
写屏障可以使得应用线程加载存储在堆的特定地址处的引用(操作906)。如上所述,引用包括存储指示GC状态的信息的瞬态颜色部分。
应用线程可以将加载的当前引用的一部分(来自操作906)与(操作904的)GC确定的GC状态信息进行比较,以确定当前引用的该部分是否与所确定的GC状态信息相匹配(操作908)。写屏障使得应用线程至少将存储在当前引用的加载颜色部分中的标记奇偶校验的指示与由所确定的GC状态信息指示的当前标记奇偶校验进行比较。在一些实施例中,写屏障使得比较附加GC状态,包括将存储在当前引用的加载颜色部分中的记忆集奇偶校验和由所确定的GC状态信息指示的当前记忆集奇偶校验进行比较。
在一些情况下,写屏障可以使得系统将来自当前引用的颜色信息整体与由GC指定的当前“良好”颜色进行比较。作为特定示例,写屏障可以使得应用线程执行按位比较操作,以(例如,使用测试指令)将来自加载的当前引用的特定数量的位(例如,字节、字)与由GC指定的当前“良好”颜色进行比较。作为另一个示例,写屏障可以使得应用线程对当前引用的加载颜色部分以及由GC指定的当前“良好”颜色的按位补码执行测试指令。
如果比较指示当前引用的加载部分与所确定的GC状态信息相匹配(操作908中的“是”),那么这指示针对该引用的地址的当前写入不是自从标记阶段开始以来针对该地址的第一次写入。一个或多个实施例包括将引用存储到堆存储器(操作912)。应用线程采用“快速路径”,其涉及跳过操作,诸如避免将加载的当前引用存储到SATB数据结构供GC使用。而是,应用线程直接执行操作91 2,这将在下面进一步讨论。
如果比较指示当前引用的加载部分与所确定的GC状态信息不匹配(操作908中的“否”),那么这指示针对该引用的地址的当前写入是自从标记阶段开始以来针对该地址的第一次写入。系统写屏障可以使得应用线程将加载的当前引用存储到SATB数据结构以供GC分析(操作910)。特别地,GC可以遍历数据结构中的引用作为标记处理的一部分。例如,GC标记处理可以包括遍历存储在数据结构中的引用的传递闭包。在实施例中,SATB数据结构是存储引用的链表。
此后,写屏障可以使得应用线程将来自调用栈的引用存储到堆存储器(操作912)。在实施例中,来自调用栈的引用不具有关于哪个GC状态是该引用的当前GC状态的任何指示。该引用不包括指示关于该引用的GC操作的进度的任何信息或元数据。在另一个实施例中,该引用不具有关于一组互斥GC状态中的哪一个是该引用的当前GC状态的任何指示;但是,该引用可以包括关于其它GC状态的信息(例如,引用的年龄)。在实施例中,要写入的引用可能先前已被解除引用(由当前尝试将该引用写入到堆存储器和/或另一个线程的应用线程解除引用)。
应用线程可以创建良好位掩码,其在最低位中包括所确定的“良好”GC状态,并且在所有其它位中包括0。一个或多个实施例包括应用线程将引用(具有添加的将良好GC状态作为该引用的当前GC状态的指示)存储到堆存储器上。应用线程从调用栈中检索引用,并添加了将良好GC状态作为该引用的当前GC状态的指示。例如,应用线程可以对来自调用栈的引用应用逻辑按位左移操作。按位左移操作导致引用的位被左移n次,其中n等于良好移位值。应用线程可以执行被移位的引用和良好位掩码的逻辑OR。应用将引用存储到堆存储器上,该引用包括该引用的当前GC状态的指示。
以这种方式,写屏障可以限制对SATB数据结构的写入,使得仅对特定引用的第一次写入使得引用被添加到数据结构。这确保了在GC标记处理期间,存储到堆的所有对象都可以被标记为存活,同时限制SATB数据结构中包含的引用的数量。
6.其它方面;扩展
实施例针对具有包括硬件处理器并且被配置为执行本文所述和/或在以下权利要求中任何一项所述的任何操作的一个或多个设备的系统。
在实施例中,非暂态计算机可读存储介质包括指令,当所述指令由一个或多个硬件处理器执行时,使得执行本文所述和/或在权利要求中任何一项所述的任何操作。
本文所述的特征和功能的任何组合可以根据一个或多个实施例来使用。在前面的说明书中,各种实施例已经参考许多具体细节进行了描述,这些具体细节可以从一种实现方式到另一种实现方式而不同。因此,说明书和附图应当在说明性而不是限制性的意义上加以考虑。本发明范围的唯一且排他指示,以及申请人预期要作为本发明范围的是由本申请产生的权利要求集合的字面和等效范围,以这种权利要求产生的具体形式,包括任何后续的更正。
7.硬件概述
根据一个实施例,本文所描述的技术由一个或多个专用计算设备来实现。专用计算设备可以是硬连线的以执行技术,或者可以包括诸如被永久性地编程以执行技术的一个或多个专用集成电路(ASIC)或现场可编程门阵列(FPGA)之类的数字电子设备,或者可以包括编程为根据固件、存储器、其它存储装置或组合中的程序指令执行技术的一个或多个通用硬件处理器。这些专用计算设备还可以将自定义的硬接线逻辑、ASIC或FPGA与自定义的编程组合来实现技术。专用计算设备可以是台式计算机系统、便携式计算机系统、手持式设备、联网设备或结合硬连线和/或程序逻辑来实现技术的任何其它设备。
例如,图10是示出可以在其上实现本发明的实施例的计算机系统1000的框图。计算机系统1000包括总线1002或用于传送信息的其它通信机制,以及与总线1002耦合用于处理信息的硬件处理器1004。硬件处理器1004可以是例如通用微处理器。
计算机系统1000还包括耦合到总线1002用于存储信息和要由处理器1004执行的指令的主存储器1006,诸如随机存取存储器(RAM)或其它动态存储设备。主存储器1006也可以用于在要由处理器1004执行的指令执行期间存储临时变量或其它中间信息。当这些指令被存储在处理器1004可访问的非暂态存储介质中时,它们使计算机系统1000成为被定制以执行指令中指定的操作的专用机器。
计算机系统1000还包括耦合到总线1002用于存储静态信息和用于处理器1004的指令的只读存储器(ROM)1008或其它静态存储设备。提供了诸如磁盘或光盘的存储设备1010,并且存储设备1010被耦合到总线1002,用于存储信息和指令。
计算机系统1000可以经由总线1002耦合到显示器1012,诸如阴极射线管(CRT),用于向计算机用户显示信息。输入设备1014(其包括字母数字和其它键)被耦合到总线1002,用于将信息和命令选择传送到处理器1004。另一种类型的用户输入设备是光标控件1016,诸如鼠标、轨迹球、或光标方向键,用于向处理器1004传送方向信息和命令选择并且用于控制光标在显示器1012上的移动。这种输入设备通常具有在两个轴(第一轴(例如,x)和第二轴(例如,y))中的两个自由度,这允许设备在平面中指定位置。
计算机系统1000可以使用定制的硬连线逻辑、一个或多个ASIC或FPGA、固件和/或程序逻辑来实现本文描述的技术,这些定制的硬连线逻辑、一个或多个ASIC或FPGA、固件和/或程序逻辑与计算机系统结合使计算机系统1000成为或将计算机系统1000编程为专用机器。根据一个实施例,本文的技术由计算机系统1000响应于处理器1004执行主存储器1006中包含的一条或多条指令的一个或多个序列而执行。这些指令可以从另一个存储介质(诸如存储设备1010)读取到主存储器1006中。包含在主存储器1006中的指令序列的执行使处理器1004执行本文描述的处理步骤。在替代实施例中,可以使用硬连线电路系统代替软件指令或与软件指令组合使用。
如本文所使用的术语“存储介质”是指存储使机器以特定方式操作的数据和/或指令的任何非暂态介质。这种存储介质可以包括非易失性介质和/或易失性介质。非易失性介质包括例如光盘或磁盘,诸如存储设备1010。易失性介质包括动态存储器,诸如主存储器1006。存储介质的常见形式包括例如软盘、柔性盘、硬盘、固态驱动器、磁带或任何其它磁性数据存储介质、CD-ROM、任何其它光学数据存储介质、具有孔模式的任何物理介质、RAM、PROM和EPROM、FLASH-EPROM、NVRAM、任何其它存储器芯片或盒带。
存储介质与传输介质不同但可以与传输介质结合使用。传输介质参与在存储介质之间传输信息。例如,传输介质包括同轴电缆、铜线和光纤,包括包含总线1002的电线。传输介质还可以采取声波或光波的形式,诸如在无线电波和红外线数据通信期间生成的那些波。
各种形式的介质可以涉及将一条或多条指令的一个或多个序列携带到处理器1004以供执行。例如,指令最初可以被携带在远程计算机的磁盘或固态驱动器上。远程计算机可以将指令加载到其动态存储器中,并且使用调制解调器经电话线发送指令。计算机系统1000本地的调制解调器可以接收电话线上的数据,并且使用红外线发射器将数据转换为红外线信号。红外线探测器可以接收在红外线信号中携带的数据,并且适当的电路系统可以将数据放在总线1002上。总线1002将数据携带到主存储器1006,处理器1004从该主存储器1006检索并执行指令。由主存储器1006接收到的指令可以可选地在被处理器1004执行之前或执行之后存储在存储设备1010上。
计算机系统1000还包括耦合到总线1002的通信接口1018。通信接口1018提供耦合到网络链路1020的双向数据通信,其中网络链路1020连接到本地网络1022。例如,通信接口1018可以是综合业务数字网(ISDN)卡、电缆调制解调器、卫星调制解调器、或向对应类型的电话线提供数据通信连接的调制解调器。作为另一个示例,通信接口1018可以是提供到兼容的局域网(LAN)的数据通信连接的LAN卡。也可以实现无线链路。在任何这种实现中,通信接口1018都发送和接收携带表示各种类型信息的数字数据流的电信号、电磁信号或光信号。
网络链路1020通常通过一个或多个网络向其它数据设备提供数据通信。例如,网络链路1020可以通过本地网络1022提供到主计算机1024或到由互联网服务提供商(ISP)1026操作的数据设备的连接。ISP 1026又通过现在通常称为“互联网”1028的世界范围的分组数据通信网络提供数据通信服务。本地网络1022和互联网1028二者都使用携带数字数据流的电信号、电磁信号或光信号。通过各种网络的信号以及在网络链路1020上并且通过通信接口1018的信号是传输介质的示例形式,其中信息将数字数据携带到计算机系统1000或者携带来自计算机系统1000的数字数据。
计算机系统1000可以通过(一个或多个)网络、网络链路1020和通信接口1018发送消息和接收数据,包括程序代码。在互联网示例中,服务器1030可以通过互联网1028、ISP1026、本地网络1022和通信接口1018传送对应用程序的请求代码。
接收到的代码可以在其被接收到时由处理器1004执行,和/或存储在存储设备1010或其它非易失性存储器中以供以后执行。
在前面的说明书中,已经参考因实现而异的许多具体细节描述了实施例。因此,说明书和附图应当被认为是说明性的而不是限制性的。本发明的范围的唯一且排他的指示以及申请人预期作为本发明的范围的内容是从本申请中发出的权利要求集合的字面和等同范围,以这种权利要求发出的具体形式,包括任何后续的更正。

Claims (10)

1.一种或多种存储指令的非暂态机器可读介质,所述指令在由一个或多个处理器执行时,使得执行操作,所述操作包括:
针对堆存储器中的多个对象发起执行垃圾收集标记处理;
当垃圾收集标记处理正在执行时:
从第一突变线程接收用于覆写所述多个对象中的对象的第一引用字段的第一请求,该对象至少包括第一引用,并且第一请求包括要写入到第一引用字段的第二引用;
响应于接收到第一请求:
确定垃圾收集标记处理正在遍历的所述多个对象的当前标记奇偶校验;
从堆中加载第一引用,第一引用包括标记元数据;
确定第一引用的标记元数据与当前标记奇偶校验不匹配;
响应于确定第一引用的标记元数据与当前标记奇偶校验不匹配:
将第一引用添加到标记列表以供垃圾收集标记处理进行分析;
修改第二引用以包括当前标记奇偶校验作为标记元数据;
将修改后的第二引用存储到第一引用字段。
2.如权利要求1所述的介质,所述操作还包括:
当垃圾收集标记处理正在执行时:
从第二突变线程接收用于覆写该对象的第一引用字段的第二请求,第二请求在第一请求之后被接收到并且至少包括要写入到第一引用字段的第三引用;
响应于接收到第二请求:
确定垃圾收集标记处理正在遍历的所述多个对象的当前标记奇偶校验;
从堆中加载第二引用,第二引用包括标记元数据;
确定第二引用的标记元数据与当前标记奇偶校验相匹配;
响应于确定第二引用的标记元数据与当前标记奇偶校验相匹配:
避免将第二引用添加到标记列表;
修改第三引用以包括当前标记奇偶校验作为标记元数据;
将修改后的第三引用存储到第一引用字段。
3.如权利要求1所述的介质,其中确定第一引用的标记元数据与当前标记奇偶校验不匹配包括:执行第一引用的元数据部分和由垃圾收集处理提供的标记奇偶校验信息的按位比较操作。
4.如权利要求1所述的介质,其中修改第二引用以包括当前标记奇偶校验作为标记元数据包括:
对第二引用执行按位移位操作,按位移位操作(a)从第二引用的最高部分移除特定数量的位,以及(b)在第二引用的最低部分插入具有默认值的所述特定数量的位;以及
对第二引用执行按位逻辑操作,以用当前标记奇偶校验覆写被插入到第二引用的所述最低部分中的所述特定数量的位。
5.如权利要求4所述的介质,其中位的所述特定数量由垃圾收集处理指定。
6.如权利要求1所述的介质,其中所述当前标记奇偶校验由垃圾收集处理指定。
7.如权利要求1所述的介质,其中所述垃圾收集处理是包括年轻代和老年代的多代垃圾收集处理,并且其中所述当前标记奇偶校验包括当前年轻代标记奇偶校验和当前老年代标记奇偶校验。
8.一种方法,包括如权利要求1-7中的任一项所述的操作。
9.一种系统,包括:
至少一个设备,包括硬件处理器;
所述系统被配置为执行如权利要求1-7中的任一项所述的操作。
10.一种包括用于执行如权利要求1-7中的任一项所述的操作的装置的系统。
CN202280046339.8A 2021-05-19 2022-05-16 Z垃圾收集器中的开始时快照标记 Pending CN117597671A (zh)

Applications Claiming Priority (6)

Application Number Priority Date Filing Date Title
US63/190,625 2021-05-19
US63/190,621 2021-05-19
US63/190,617 2021-05-19
US17/303,635 2021-06-03
US17/303,635 US11734171B2 (en) 2021-05-19 2021-06-03 Snapshot at the beginning marking in Z garbage collector
PCT/US2022/029484 WO2022245749A1 (en) 2021-05-19 2022-05-16 Snapshot at the beginning marking in z garbage collector

Publications (1)

Publication Number Publication Date
CN117597671A true CN117597671A (zh) 2024-02-23

Family

ID=89922808

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202280046339.8A Pending CN117597671A (zh) 2021-05-19 2022-05-16 Z垃圾收集器中的开始时快照标记

Country Status (1)

Country Link
CN (1) CN117597671A (zh)

Similar Documents

Publication Publication Date Title
US11573894B2 (en) Tracking garbage collection states of references
US10719337B2 (en) Container-based language runtime loading an isolated method
US11474832B2 (en) Intelligently determining a virtual machine configuration during runtime based on garbage collection characteristics
CN117581214A (zh) 用于分代z垃圾收集器中的记忆集维护的写屏障
US10733095B2 (en) Performing garbage collection on an object array using array chunk references
CN117597671A (zh) Z垃圾收集器中的开始时快照标记
CN117581215A (zh) Z垃圾收集器中的无色根实现
US11573794B2 (en) Implementing state-based frame barriers to process colorless roots during concurrent execution
US11513954B2 (en) Consolidated and concurrent remapping and identification for colorless roots
US11875193B2 (en) Tracking frame states of call stack frames including colorless roots
US11789863B2 (en) On-the-fly remembered set data structure adaptation
WO2022245659A1 (en) Colorless roots implementation in z garbage collector
EP4341819A1 (en) Snapshot at the beginning marking in z garbage collector
WO2022245954A1 (en) Write barrier for remembered set maintenance in generational z garbage collector
US20240126688A1 (en) Lazy compaction in garbage collection

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination