-XX:PretenureSizeThreshold的預設值和作用淺析
一、背景
《深入理解Java虛擬機器》第93頁,3.6.2 大物件直接進入老年代。
講到大物件主要指字串和陣列,虛擬機器提供了一個-XX:PretenureSizeThreshold引數,大於這個值的引數直接在老年代分配。
這樣做的目的是避免在Eden區和兩個Survivor區之間發生大量的記憶體複製(新生代採用複製演算法)。
但是這裡沒講清楚預設值是多少,預設會不會“大”物件直接進入老年代。
二、解析
2.1 參考文章
找到了一篇相關問題的文章《Frequently Asked Questions about Garbage Collection in the HotspotTM JavaTM Virtual Machine》
第29條:Do objects ever get allocated directly into the old generation?
In 1.4.1 there two situations where allocation may occur directly into the old generation.
有兩種情況,物件會直接分配到老年代。
If an allocation fails in the young generation and the object is a large array that does not contain any references to objects, it can be allocated directly into the old generation. In some select instances, this strategy was intended to avoid a collection of the young generation by allocating from the old generation.如果在新生代分配失敗且物件是一個不含任何物件引用的大陣列,可被直接分配到老年代。
透過在老年代的分配避免新生代的一次垃圾回收。
There is a flag (available in 1.4.2 and later) l-XX:PretenureSizeThreshold=<byte size> that can be set to limit the size of allocations in the young generation. Any allocation larger than this will not be attempted in the young generation and so will be allocated out of the old generation.XX:PretenureSizeThreshold=<位元組大小>可以設分配到新生代物件的大小限制。
任何比這個大的物件都不會嘗試在新生代分配,將在老年代分配記憶體。
The threshold size for 1) is 64k words. The default size for PretenureSizeThreshold is 0 which says that any size can be allocated in the young generation.PretenureSizeThreshold 預設值是0,意味著任何物件都會現在新生代分配記憶體。
2.2 實驗解析
設定虛擬機器引數
-Xms2048m
-Xmx2048m
-Xmn1024m
-XX:+UseConcMarkSweepGC-XX:SurvivorRatio=8
-Xms表示初始化堆記憶體
-Xmx 表示最大堆記憶體
-Xmn表示新生代的記憶體
-XX:SurvivorRatio=8表示新生代的Eden佔8/10,S1和S2各佔1/10.
因此Eden的記憶體大小為:0.8*1024*1024*1024位元組 約為819**1024*1024
上程式碼
public class Test { public static void main(String[] args) throws Exception { byte[] array = new byte[700 * 1024 * 1024];//734003216 for (MemoryPoolMXBean memoryPoolMXBean : ManagementFactory.getMemoryPoolMXBeans()) { System.out.println(memoryPoolMXBean.getName() + " 總量:" + memoryPoolMXBean.getUsage().getCommitted() + " 使用的記憶體:" + memoryPoolMXBean.getUsage().getUsed()); } } }
可以看到應該被分配到了新生代的Eden區
Code Cache 總量:2555904 使用的記憶體:1206528
Metaspace 總量:4980736 使用的記憶體:3426872
Compressed Class Space 總量:524288 使用的記憶體:371280
Par Eden Space 總量:859045888 使用的記憶體:785546016
Par Survivor Space 總量:107347968 使用的記憶體:0
CMS Old Gen 總量:1073741824 使用的記憶體:0
將陣列物件增加到大於Eden區記憶體大小
byte[] array = new byte[900 * 1024 * 1024];
會導致新生代分配失敗,直接進入老年代
Code Cache 總量:2555904 使用的記憶體:1197824
Metaspace 總量:4980736 使用的記憶體:3426024
Compressed Class Space 總量:524288 使用的記憶體:371280
Par Eden Space 總量:859045888 使用的記憶體:34361864
Par Survivor Space 總量:107347968 使用的記憶體:0
CMS Old Gen 總量:1073741824 使用的記憶體:943718416
且此時透過jstat -gcutil vmpid命令檢視垃圾回收狀態,發現並沒有YGC.
然後我們將位元組陣列改回 小於Eden去記憶體
byte[] array = new byte[700 * 1024 * 1024];
並新增啟動引數-XX:PretenureSizeThreshold=100000000
Code Cache 總量:2555904 使用的記憶體:1172160
Metaspace 總量:4980736 使用的記憶體:3412552
Compressed Class Space 總量:524288 使用的記憶體:371280
Par Eden Space 總量:859045888 使用的記憶體:51542800
Par Survivor Space 總量:107347968 使用的記憶體:0
CMS Old Gen 總量:1073741824 使用的記憶體:734003216
發現即使新生代足夠分配,大於這個值的大物件也直接在老年代分配。
從而印證了文件的說法。
三、總結
多查權威參考文件。
多試驗看效果
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756/viewspace-2823182/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 預設值的作用域
- CSS變數的作用域和預設值CSS變數
- 淺析Java中的雜湊值HashCode的作用及用法Java
- 淺析 App_KEY 的作用APP
- 淺析反向代理的原理與作用
- 淺析number型別的值型別
- ${VAR:=預設值}和${VAR:-預設值} 區別
- 淺析HDFS架構和設計架構
- 淺析賦值、淺拷貝、深拷貝的區別賦值
- 淺析Spring的IoC和DISpring
- 淺析IOC 和 DI
- 淺析Convert,Parse和TryParse
- 淺析InnoDB引擎的索引和索引原理索引
- 淺析 DjangoModel 設計禪道Django
- 淺談Java的反射機制和作用Java反射
- 淺析企業運用,大資料管理的特點及作用!大資料
- 生成 URL 的 預設值
- HTML 元素的預設值HTML
- MySQL預設資料庫的作用MySql資料庫
- 淺析pplx庫的設計與實現。
- 淺析靜態IP的用途和優點
- 淺析c++11中的“=default“和“=delete“C++delete
- 淺析package.json中的devdependencies 和 dependenciesPackageJSONdev
- iOS 設計模式淺析 0 – 前言iOS設計模式
- 淺析面向協議程式設計協議程式設計
- 淺析mybatis中${}和#{}取值區別MyBatis
- AnalyticDB實現和特點淺析
- 淺析Beautiful Soup庫和Lxml庫XML
- java閉包和回撥淺析Java
- HTML常用元素的預設值HTML
- 淺析數字化價值,如何保障數字化價值實現?
- iOS Block淺淺析iOSBloC
- 函式(三)作用域之變數作用域、函式巢狀中區域性函式作用域、預設值引數作用域函式變數巢狀
- 淺析DHCP的概念和原理(中科三方)
- 預設建構函式和帶預設值的建構函式不能同時存在函式
- 淺析RedisRedis
- Jvm 淺析JVM
- CGLib淺析CGLib