5. JDK12 新特性
makefile复制代码
189:
Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)Shenandoah: 低暂停时间垃圾收集器(实验)
230:
Microbenchmark Suite微基准测试套件
325:
Switch Expressions (Preview)开关表达式(预览)
334:
JVM Constants APIJVM 常量 API
340:
One AArch64 Port, Not Two一个 AArch64端口,不是两个
341:
Default CDS Archives默认的 CDS 存档
344:
Abortable Mixed Collections for G1可流产的 G1混合集合
346:
Promptly Return Unused Committed Memory from G1从 G1及时返回未使用的提交内存
5.1 Switch表达式(Preview)
JDK 12引入了一个名为"Switch表达式(Preview)"的功能,它对Switch语句进行了改进,使其更加灵活和易用。Switch表达式允许在Switch语句中使用Lambda风格的语法进行模式匹配,并直接返回值。 在传统的Switch语句中,每个case分支都需要使用break
语句来防止掉落到下一个分支。而在Switch表达式中,我们可以使用箭头(->
)来直接返回值,而不需要使用break
语句。 以下是Switch表达式的示例:
int day = 3;
String dayName = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid day";
};
在上述代码中,Switch表达式根据day
的值进行模式匹配,然后返回相应的字符串。在case分支中,可以使用逗号将多个值组合在一起,表示它们共享相同的处理逻辑。在最后的default分支中,如果没有匹配的情况,将返回"Invalid day"。 Switch表达式的语法比传统的Switch语句更简洁和易读。它可以减少重复的代码和易错的break
语句,使得代码更加清晰和紧凑。 需要注意的是,Switch表达式在JDK 12中是作为预览功能引入的,意味着它是一项实验性的功能,可能会在后续的JDK版本中进行调整和改进。要使用Switch表达式,需要确保在编译器选项中启用了预览功能,例如使用--enable-preview
选项。
5.2 微基准测试套件
JDK 12引入了Microbenchmark Suite(JEP 230),它是一个用于编写和运行微基准测试的套件。微基准测试是一种专门用于测量小块代码片段的性能的测试方法。 Microbenchmark Suite提供了一组工具和库,帮助开发人员编写和执行微基准测试,并提供准确的性能测量结果。以下是Microbenchmark Suite的一些关键特点:
- @Benchmark注解:Microbenchmark Suite通过
@Benchmark
注解标记要进行性能测试的方法。这样,开发人员可以将注解添加到他们想要测试的方法上,以指示该方法是一个微基准测试。 - Blackhole类:Microbenchmark Suite提供了
Blackhole
类,用于消耗被测试方法的结果,以防止JVM进行优化和消除未使用的代码。这样可以更准确地测量方法的性能。 - 测试运行器:Microbenchmark Suite提供了一个测试运行器,用于执行微基准测试,并生成关于每个测试的性能测量结果。测试运行器可以配置以控制测试的参数和执行方式。
通过使用Microbenchmark Suite,开发人员可以编写和运行精确的微基准测试,以测量特定代码片段的性能,并进行性能优化。微基准测试可以帮助开发人员识别潜在的性能问题、比较不同实现的性能差异,并确定性能优化的方向。 需要注意的是,微基准测试需要谨慎使用,因为性能测试结果可能会受到多种因素的影响,如硬件环境、垃圾收集器、JVM参数等。因此,在进行微基准测试时,需要了解其原理、正确使用工具和库,并进行合理的结果解释和分析。
5.3 JVM 常量 API
在 JDK 12 中,Java 虚拟机(JVM)引入了一些常量 API,以便在运行时获取 JVM 的一些常量信息。这些常量 API 主要位于 java.lang.constant
包中,提供了一种安全和类型安全的方式来访问这些常量。 以下是 JDK 12 中一些常量 API 的主要类和接口:
java.lang.constant.Constable
:这是一个标记接口,表示一个常量值可以在编译时被抽象为常量。这个接口有助于在编译时执行常量折叠和内联优化。java.lang.constant.ConstantDesc
:这是一个通用的常量描述符接口,用于表示各种类型的常量。它是所有常量类型的父接口。java.lang.constant.ClassDesc
:这是一个常量描述符接口,表示一个类类型的常量。它提供了获取类名、包名等信息的方法。java.lang.constant.MethodTypeDesc
:这是一个常量描述符接口,表示方法类型的常量。它提供了获取方法参数类型和返回类型的方法。java.lang.constant.DynamicCallSiteDesc
:这是一个常量描述符接口,表示一个动态调用点(Dynamic Call Site)的常量。它提供了获取调用点信息的方法。java.lang.constant.DirectMethodHandleDesc
:这是一个常量描述符接口,表示一个直接方法句柄(Direct Method Handle)的常量。它提供了获取方法句柄信息的方法。java.lang.constant.ConstableDesc
:这是一个常量描述符接口,表示一个常量值的常量。它提供了获取常量值的方法。
除了上述接口,还有一些其他类和接口,用于支持不同类型的常量,如字段常量、模块常量等。 这些常量 API 的引入使得开发人员可以更方便地在运行时访问和处理 JVM 中的常量信息,从而实现更高效和更安全的代码。
5.4 默认CDS档案
JDK 12 引入了一个新功能,称为默认 CDS(Class Data Sharing)档案。CDS 是一项技术,它允许在 JVM 启动时将类的元数据和字节码预先加载到共享存档文件中,以提高应用程序的启动时间和内存占用。 在 JDK 12 中,默认 CDS 提供了一种简化的方法来创建和使用 CDS 档案。它允许您使用默认的配置文件来自动创建 CDS 档案,而无需手动指定类列表。 以下是使用默认 CDS 档案的步骤:
- 运行应用程序时,添加
-XX:DumpLoadedClassList=<classlist.txt>
参数。这将在应用程序退出时生成一个类列表文件classlist.txt
,其中包含了应用程序加载的所有类。 - 使用
jlink
命令创建一个包含默认 CDS 档案的自定义运行时映像。添加--class-list=<classlist.txt>
参数,其中<classlist.txt>
是第一步生成的类列表文件的路径。 - 在启动应用程序时,使用
java
命令指定-Xshare:dump
参数来生成默认的 CDS 档案。这将根据默认的配置文件(<JDK>/lib/classlist
)自动创建 CDS 档案。 - 在后续启动应用程序时,使用
-Xshare:on
参数来启用默认 CDS 档案。这将使用预先生成的 CDS 档案来加速应用程序的启动。
需要注意的是,默认 CDS 档案功能在不同的平台和 JDK 发行版中可能有所差异。在一些平台上,CDS 功能可能需要特定的许可证。此外,CDS 档案的创建和使用可能会因应用程序的特性而有所不同,因此建议参考相关的 JDK 文档和文档以获取详细信息和指导。
5.5 G1 的可流动混合收集
G1的目标之一是满足用户提供的暂停时间目标以暂停其收集暂停。G1使用高级分析引擎来选择在集合期间 要完成的工作量(这部分基于应用程序行为)。此选择的结果是一组称为集合集的区域。一旦确定了集合集并且 已经开始集合,则G1必须在不停止的情况下收集集合集的所有区域中的所有活动对象。如果启发式选择过大的收 集,则此行为可导致G1超过暂停时间目标,例如,如果应用程序的行为发生变化,以致启发式工作在“陈旧”数据 上,则可能发生这种情况。特别是在混合集合期间可以观察到这种情况,其中集合集通常可以包含太多旧区域。 需要一种机制来检测启发式方法何时反复为集合选择错误的工作量,如果是,则让G1逐步递增地执行收集工作, 其中集合可以在每个步骤之后中止。这种机制将允许G1更频繁地满足暂停时间目标。 其他详细信息请参考官网