通過(guò)活動(dòng)對(duì)象大小的信息,可以做出關(guān)于Java堆的大小有根據(jù)的決定,以及可以估計(jì)出最壞情況下會(huì)導(dǎo)致的延遲。
比較常規(guī)是,Java堆大小的初始化值和最大值(通過(guò)-Xms和-Xmx選項(xiàng)來(lái)指定)應(yīng)該是old代活動(dòng)對(duì)象的大小的3到4倍。
在上圖中顯示的FullGC信息中,在FullGC之后old代的大小是295111K,差不多是295M,即活動(dòng)的對(duì)象的大小是295M。因此,推薦的Java堆的初始化和最大值應(yīng)該是885M到1180M,即可以設(shè)置為-Xms885m -Xmx1180m。在這個(gè)例子中,Java堆的大小是1048570K差不多1048M,在推薦值范圍內(nèi)。
另外一個(gè)常規(guī)是,permanent的初始值和最大值(-XX:PermSize和-XX:MaxPermSize)應(yīng)該permanent代活動(dòng)對(duì)象大小的1.2到1.5倍。在上圖中看到在FullGC之后permanent代占用空間是32390K,差不多32M。因此,permanent代的推薦大小是38M到48M,即可以設(shè)置為-XX:PermSize=48m -XX:MaxPermSize=48m(1.5倍)。這個(gè)例子里面,permanent代的空間大小是65536K即64M,大出了17M,不過(guò)在1G內(nèi)存的系統(tǒng)的中,這個(gè)數(shù)值完全可以忍受。
另外一個(gè)常規(guī)是,young代空間應(yīng)該是old代活動(dòng)對(duì)象大小的1到1.5倍。那么在這里例子中,young代的大小可以設(shè)置為295M到442M。本例里面,young代的空間大小的358400K,差不多358M,在推薦值中間。
如果推薦的Java堆的初始值和最大值是活動(dòng)對(duì)象大小3到4倍,而young代的推薦只是1到1.5倍,那么old代空間大小應(yīng)該是2到3倍。
通過(guò)以上規(guī)則,我們可以使用的Java命令可以是這樣的:
- java -Xms1180m -Xmx1180m -Xmn295m -XX:PermSize=48m -XX:MaxPermSize=48m
另外一些考慮
本節(jié)將提及到在進(jìn)行應(yīng)用內(nèi)存占用評(píng)估的時(shí)候,另外一些需要記住的點(diǎn)。首先,必須要知道,前面只是評(píng)估的Java堆的大小,而不是Java應(yīng)用占用的所有的內(nèi)存,如果要查看Java應(yīng)用占用的所有內(nèi)存在linux下可以通過(guò)top命令查看或者在window下面通過(guò)任務(wù)管理器來(lái)查看,盡管Java堆的大小可能對(duì)Java應(yīng)用占用內(nèi)存做出了最大的貢獻(xiàn)。 比如說(shuō),為了存儲(chǔ)線程堆棧,應(yīng)用需要額外的內(nèi)存,越多的線程,越多內(nèi)存被線程棧消耗,越深的方法間調(diào)用,線程棧越多。另外,本地庫(kù)需要分配額外的內(nèi)存,I/O緩存也需要額外的內(nèi)存。應(yīng)用的內(nèi)存消耗需要評(píng)估到應(yīng)用任何一個(gè)會(huì)消耗內(nèi)存的地方。
記住,這一步操作不一定能夠滿足應(yīng)用內(nèi)存消耗的需求,如果不能滿足,就回過(guò)頭來(lái)看需求是否合理或者修改應(yīng)用程序。比較可行的一種辦法是修改應(yīng)用程序減小對(duì)象的分配,從而減少內(nèi)存的消耗。
Java堆的大小計(jì)算僅僅只是開始,根據(jù)需求,在后面的優(yōu)化步驟中可能會(huì)修改。