JDK/Java 13:ZGC未使用堆內存歸還操作系統

翻譯自:JEP 351

一、摘要

增強ZGC,將未使用的堆內存返回給操作系統。

二、動機

目前ZGC不會將未使用的內存歸還給操作系統,即使該內存已經很長時間沒有使用了。這種行爲並不適合所有類型的應用程序和環境,特別是那些需要考慮內存佔用的應用程序和環境。例如:

  • 按資源使用付費的容器環境。

  • 應用程序可能長時間處於空閒狀態並與許多其他應用程序共享或競爭資源的環境。

  • 應用程序在執行期間可能有非常不同的堆空間需求。例如,啓動期間所需的堆可能大於稍後在穩定狀態執行期間所需的堆。

HotSpot中的其他垃圾收集器(如G1和Shenandoah)已經提供了這種功能,該功能對於一些用戶非常有用。將此功能添加到ZGC將受到這些用戶的歡迎。

三、描述

ZGC堆由一組稱爲ZPages的堆區域組成。每個Zpage與數量可變的已提交內存相關聯。當ZGC壓縮堆時,ZPages被釋放並插入到頁面緩存ZPageCache中。頁面緩存中的ZPages可以重用,以滿足新的堆分配,在這種情況下,它們將從緩存中刪除。頁面緩存對性能至關重要,因爲提交和不提交內存都是昂貴的操作。

頁面緩存中的ZPages集合表示堆中未使用的部分,這些部分可以歸還給操作系統。因此,取消提交內存可以通過簡單地從頁面緩存中刪除一組精心選擇的ZPages,並取消與這些頁面關聯的內存的提交來完成。頁面緩存已經將ZPages保持在最近最少使用(LRU)的順序,並按大小(小、中、大)進行分隔,因此清除ZPages和取消提交內存的機制相對簡單。挑戰在於設計策略來決定何時從緩存中驅逐ZPage。

一個簡單的策略是設置一個timeout或delay值,該值指定ZPage在被清除之前可以在頁面緩存中駐留多長時間。這個超時將有一些合理的默認值,可以使用命令行選項覆蓋它。Shenandoah GC使用這樣的策略,默認值爲5分鐘,命令行選項-XX:ShenandoahUncommitDelay=<milliseconds>來覆蓋默認值。

類似上述策略的效果可能相當不錯。然而,人們也可以設想更復雜的策略,不涉及添加新的命令行選項。例如,根據GC頻率或其他數據找到合適超時值的啓發式方法。我們將首先提供一個簡單的超時策略,使用-XX:ZUncommitDelay=<seconds>選項,稍後再提供一個更復雜的策略(如果找到了)。

默認情況下將啓用uncommit功能。但是無論策略如何決定,ZGC都不能把堆內存降到低於Xms。這就意味着,如果Xmx和Xms相等的話,這個能力就失效了,-XX:-ZUncommit這個參數也能讓這個內存管理能力失效。

最後,Linux/x64上的ZGC使用tmpfs或hugetlbfs文件來支持堆。這些文件使用的未提交內存需要fallocate(2)和FALLOC_FL_PUNCH_HOLE支持,FALLOC_FL_PUNCH_HOLE支持最早出現在Linux 3.5 (tmpfs)和4.3(hugetlbfs)中。在舊的Linux內核上運行時,ZGC應該像以前一樣繼續工作,但是禁用了uncommit功能。

< END >

喜歡就點個在看 or 轉發個朋友圈唄

            

衣舞晨風

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章