眾所周知
jvm的內存是受限的
一為機器的體系架構
二為操作系統本身
x
x
SPARC
的內存映射是不同
而各操作系統的內存管理機制也有區別
以下是來自;
Heap設定與垃圾回收Java Heap分為
個區
Young
Old和Permanent
Young保存剛實例化的對象
當該區被填滿時
GC會將對象移到Old區
Permanent區則負責保存反射對象
本文不討論該區
JVM的Heap分配可以使用
X參數設定
Xms
初始Heap大小
Xmx
java heap最大值
Xmn
young generation的heap大小
JVM有
個GC線程
第一個線程負責回收Heap的Young區
第二個線程在Heap不足時
遍歷Heap
將Young 區升級為Older區
Older區的大小等於
Xmx減去
Xmn
不能將
Xms的值設的過大
因為第二個線程被迫運行會降低JVM的性能
為什麼一些程序頻繁發生GC?有如下原因
l 程序內調用了System
gc()或Runtime
gc()
l 一些中間件軟件調用自己的GC方法
此時需要設置參數禁止這些GC
l Java的Heap太小
一般默認的Heap值都很小
l 頻繁實例化對象
Release對象
此時盡量保存並重用對象
例如使用StringBuffer()和String()
如果你發現每次GC後
Heap的剩余空間會是總空間的
%
這表示你的Heap處於健康狀態
許多Server端的Java程序每次GC後最好能有
%的剩余空間
經驗之談
.Server端JVM最好將
Xms和
Xmx設為相同值
為了優化GC
最好讓
Xmn值約等於
Xmx的
/
[
]
.一個GUI程序最好是每
到
秒間運行一次GC
每次在半秒之內完成[
]
注意
.增加Heap的大小雖然會降低GC的頻率
但也增加了每次GC的時間
並且GC運行時
所有的用戶線程將暫停
也就是GC期間
Java應用程序不做任何工作
.Heap大小並不決定進程的內存使用量
進程的內存使用量要大於
Xmx定義的值
因為Java為其他任務分配內存
例如每個線程的Stack等
.Stack的設定
每個線程都有他自己的Stack
Xss
每個線程的Stack大小
Stack的大小限制著線程的數量
如果Stack過大就好導致內存溢漏
Xss參數決定Stack大小
例如
Xss
K
如果Stack太小
也會導致Stack溢漏
.硬件環境
硬件環境也影響GC的效率
例如機器的種類
內存
swap空間
和CPU的數量
如果你的程序需要頻繁創建很多transient對象
會導致JVM頻繁GC
這種情況你可以增加機器的內存
來減少Swap空間的使用[
]
.
種GC
第一種為單線程GC
也是默認的GC
該GC適用於單CPU機器
第二種為Throughput GC
是多線程的GC
適用於多CPU
使用大量線程的程序
第二種GC與第一種GC相似
不同在於GC在收集Young區是多線程的
但在Old區和第一種一樣
仍然采用單線程
XX:+UseParallelGC參數啟動該GC
第三種為Concurrent Low Pause GC
類似於第一種
適用於多CPU
並要求縮短因GC造成程序停滯的時間
這種GC可以在Old區的回收同時
運行應用程序
XX:+UseConcMarkSweepGC參數啟動該GC
第四種為Incremental Low Pause GC
適用於要求縮短因GC造成程序停滯的時間
這種GC可以在Young區回收的同時
回收一部分Old區對象
Xincgc參數啟動該GC
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25698.html