ZGC: Uncommit Unused Memory (Experimental)
在JDK12中为G1添加归还空闲内存给操作系统后,在JDK13中也为ZGC添加了此功能。
HotSpot的G1和Shenandoah这两个GC已经提供了这种能力,并且对某些用户来说,非常有用。因此,把这个特性引入ZGC会得到这些用户的欢迎。
ZGC的堆又若干个Region组成,每个Region被称之为ZPage。每个Zpage与数量可变的已提交内存相关联。当ZGC压缩堆的时候,ZPage就会释放,然后进入page cache,即ZPageCache。这些在page cache中的ZPage集合就表示没有使用部分的堆,这部分内存应该被归还给操作系统。回收内存可以简单的通过从page cache中逐出若干个选好的ZPage来实现,由于page cache是以LRU顺序保存ZPage的,并且按照尺寸(小,中,大)进行隔离,因此逐出ZPage机制和回收内存相对简单了很多,主要挑战是设计关于何时从page cache中逐出ZPage的策略。
一个简单的策略就是设定一个超时或者延迟值,表示ZPage被驱逐前,能在page cache中驻留多长时间。这个超时时间会有一个合理的默认值,也可以通过JVM参数覆盖它。Shenandoah GC用了一个类型的策略,默认超时时间是5分钟,可以通过参数-XX:ShenandoahUncommitDelay = milliseconds覆盖默认值。
像上面这样的策略可能会运作得相当好。但是,用户还可以设想更复杂的策略:不需要添加任何新的命令行选项。 例如,基于GC频率或某些其他数据找到合适超时值的启发式算法。JDK13将使用哪种具体策略目前尚未确定。可能最初只提供一个简单的超时策略,使用-XX:ZUncommitDelay = seconds选项,以后的版本会添加更复杂、更智能的策略(如果可以的话)。
uncommit能力默认是开启的,但是无论指定何种策略,ZGC都不能把堆内存降到低于Xms。这就意味着,如果Xmx和Xms相等的话,这个能力就失效了,-XX:-ZUncommit这个参数也能让这个内存管理能力失效。
Reimplement the Legacy Socket API 重新实现Socket API
JDK中的java.net.Socket 和 java.net.ServerSocket实现非常古老,可以上溯到JDK 1.0,该实现是混合了JAVA和C代码,非常难于维护和调试。另外,该实现使用线程堆栈作为I/O缓冲区,这带来一系列的移植性和可用性问题。
全新实现的NioSocketImpl,用来取代PlainSocketImpl,它的优点如下:
- 非常容易维护和Debug;
- 直接使用JDK的NIO实现,不需要自己的本地代码;
- 结合了buffer cache机制,所以不需要用线程栈来进行IO操作;
- 用JUC的锁取代synchronized修饰的方法;
Switch Expressions (Second Preview)
在 JDK 13 中为了解决 JDK 12 中switch作为表达式如果返回结果时候,case -> 右边如果是一个代码块,那么就不知道何时返回结果。因此引入了一个关键字:yield。
int result = switch (s) {
case "Foo":
yield 1;
case "Bar":
yield 2;
default:
System.out.println("Neither Foo nor Bar, hmmm...");
yield 0;
};
Text Blocks (Preview)
文本块是一个多行字符串字面值,它避免了大多数转义序列的需要,可以以预测的方式自动格式化字符串,并在需要时为开发人员提供格式控制。这是JDK 13中的预览语言特性。
HTML example
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
文本块写法
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
SQL example
String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
"WHERE `CITY` = 'INDIANAPOLIS'\n" +
"ORDER BY `EMP_ID`, `LAST_NAME`;\n";
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
完整特性
350: | Dynamic CDS Archives |
351: | ZGC: Uncommit Unused Memory |
353: | Reimplement the Legacy Socket API |
354: | Switch Expressions (Preview) |
355: | Text Blocks (Preview) |