Re: [問題] JAVA String
※ 引述《sbrhsieh (sbr)》之銘言:
: ※ 引述《garywine1201 (那是啥)》之銘言:
: : 一般而言jvm會在某段時間過後對於記憶體進行清理
: : 但其清理的是程式在jvm中佔用的記憶體量
: : 而非jvm在OS下的記憶體佔用量
: : 可以看一下這邊對於gc()函式的實驗
: : http://www.devdaily.com/java/edu/pj/pj010008/pj010008.shtml
: : 摘錄最後實驗結果
: : free memory before creating array: 4054912
: : free memory after creating array: 3852496
: : free memory after running gc(): 4064184
: : 在實驗開始之前,jvm可用記憶體為4054912
: : 這邊指的是jvm在OS當中的佔用量
: : 實驗開始之後,jvm的記憶體配置為3852496
: : 但重新釋放之後卻使得記憶體可用為4064184
: : 這邊會發現jvm多吃了OS一些空間
: 從這些數據怎麼可以推論出 JVM 從 OS 獲得更多的記憶體空間?
: 這個測試程式執行 step 2 的時候,並不表示此時 JVM 管理的 heap 是 garbage-
: free,所以等到 step 5 之後 available heap 空間變多,不代表 JVM 向 OS 索取
: 更多的記憶體。
你說的沒錯 這些數據不足以得出我的推論
要得到這個推論 要有更進一步的實驗 不過就算有實驗 結論也僅止於我的猜測
我也說明了這是我的推測
這個實驗由三個function所構成 他們的目的是這樣的
http://java.sun.com/javase/6/docs/api/java/lang/Runtime.html
freeMemory()
Returns the amount of free memory in the Java Virtual Machine.
gc()
Runs the garbage collector.
totalMemory()
Returns the total amount of memory in the Java virtual machine.
如你所說 呼叫free memory所得到的記憶體量應該不等於jvm記憶體量
所以要觀察jvm的總記憶體佔用必須呼叫totalmemory()這個函式
我對eatmemory這個函式進行修改 以取得三種不同的記憶體使用情況
1. 使用原本實驗對記憶體進行50000陣列大小的宣告
2. 重複使用迴圈呼叫eatmemory函式多達200次(事實上我嘗試了20,30,100,結果相同)
3. 直接使eatmemory的陣列宣告等同200次的大小(200*50000)
對原本的函式而言 我在Mac powerbook上面跑,得到
1.
free memory before creating array: 1584824
total memory before creating array: 2031616
total memory after eatting memory: 2031616
free memory after creating array: 1642192
free memory after running gc(): 1843584
total memory after creating array: 2031616
2.
free memory before creating array: 1584784
total memory before creating array: 2031616
total memory after eatting memory: 2031616
free memory after creating array: 1442240
free memory after running gc(): 1843584
total memory after creating array: 2031616
3.
free memory before creating array: 1584824
total memory before creating array: 2031616
total memory after eatting memory: 42033152
free memory after creating array: 1843616
free memory after running gc(): 45973928
total memory after creating array: 46161920
從這邊可以發現,jvm會有一個預設的記憶體初始大小 也就是default memory claim
從實驗一可以發現 由於內部程式記憶體並未佔用大於jvm可以負擔的能力
所以jvm的記憶體佔用始終如一
接著使用迴圈進行函式宣告,這邊發現跑完之後記憶體的總量是相同的
並沒有因為你過多的宣告而使得記憶體需求上揚
這邊顯示了jvm內建垃圾蒐集的處理效率
當迴圈往下跑時,之前沒有使用的陣列在經過一個固定時間點之後會進行清理
所以雖然實驗二的記憶體佔用會比實驗一多(用來儲存最近幾筆資料的額外空間)
但並沒有讓jvm向os要求任何記憶體
反觀實驗三
若你的程式一次性的呼叫大量的空間
並開始超出jvm的需求,jvm會直接向OS請求更多的記憶體空間(當然受限於最大值)
不過有趣的事情發生了,
在要求os提供記憶體之後,jvm的佔用暴增到420...這很合理
但當我們gc並釋放記憶體之後,jvm的記憶體佔用並未穩定,而是向上提昇了一些
也就是說,當你在處理變數時,就算你的變數只有非常低的機率會有較大的信息值
(也就是熵值,佔用bit數量的意思)
jvm一旦處理至這個變數,便會強迫自己增肥,而且會額外宣告空間以防止自己
out of memory exception
因此,在處理小程式且變數固定的情況下,jvm並不會擴張的太嚴重
但若你的程式有可能突然處理到較為複雜的變數
其就會強迫jvm進行一次增肥
而這個記憶體暫用量 會一直持續到你關閉程式為止
以目前的實驗來看似乎是沒有辦法讓jvm減瘦的
我想這好像解釋了為什麼我使用netbeans的記憶體使用量總是越來越高
即使我把額外的編輯視窗都關了 情形依舊的原因
除了這個實驗
其實我認為也還可以針對garbage collection的機制做出測試
觀察其反應的週期
也許有時候因為垃圾蒐集的不夠快,導致jvm自我增長也是有可能的
: : 因此對jvm進行free這個動作,並不會減少其耗用OS的資源能力
: : 因為jvm是自行控管記憶體配置的
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.64.235.79
推
01/24 19:46, , 1F
01/24 19:46, 1F
推
01/24 19:50, , 2F
01/24 19:50, 2F
推
01/24 21:53, , 3F
01/24 21:53, 3F
討論串 (同標題文章)