眾所周知 java的JVM有一套自己的垃圾回收機(jī)制 因此在許多情況下并不需要java程序開發(fā)人員操太多的心 然而也許也因?yàn)檫@樣 往往會造成java程序員的過分依賴而致使開發(fā)出來的程序得不到很好的優(yōu)化 或者說性能尚能提高
成都創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)資源,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575
問題的關(guān)鍵在于 不論JVM的垃圾回收機(jī)制做得多好 計(jì)算機(jī)的硬件資源是有限的 內(nèi)存更是一項(xiàng)緊張資源 因此雖然JVM為我們完成了大部分的垃圾回收 但適當(dāng)?shù)刈⒁饩幋a過程中的內(nèi)存管理還是很必要的 這樣能讓JVM回收得更順利更高效 最大限度地提高程序的效率
mark 避免在循環(huán)體內(nèi)創(chuàng)建對象
……
Object obj = null //方式一
for(int i = i k( k) secs]
……
可以看到總共有 kb的內(nèi)存被回收 耗時(shí) 秒
JVM內(nèi)存相關(guān)的參數(shù)
XX NewSize(Set the Newgeneralnation heap size)
XX MaxNewSize(Set the Maximum Newgeneralnation heap size)
XX SurvivorRatio(Set New heap size ratios)
Xms(Set minimum heap size)
Xmx(Set maximum heap size)
Xnoclassgc(取消垃圾回收)
Xss(設(shè)置棧內(nèi)存的大?。?/p>
例 java XX NewSize = m XX MaxNewSize = m XX SurvivorRatio = Xms m Xmx m MyApplication
mark 不同編譯方法的類大小
( )默認(rèn)編譯方式 javac K java
長度=代碼+源文件信息+代碼行序號表
( )調(diào)試編譯方式 javac g K java
長度=代碼+源文件信息+代碼行序號表+本地變量表
( )代碼編譯方式 javax g none K java
長度=代碼
mark 經(jīng)驗(yàn)之談
盡早釋放無用對象的引用(XX = null )
盡量少使用finalize函數(shù)
注意集合數(shù)據(jù)類型 如數(shù)組 樹 圖 鏈表等數(shù)據(jù)結(jié)構(gòu) 這些數(shù)據(jù)結(jié)構(gòu)對GC來說回收更復(fù)雜
避免在類的默認(rèn)構(gòu)造器中創(chuàng)建大量的 初始化大量的對象
避免強(qiáng)制系統(tǒng)做垃圾內(nèi)存回收
lishixinzhi/Article/program/Java/hx/201311/26273
1、首先得搞清楚什么叫內(nèi)存泄露,簡單來說就是一個東西放在內(nèi)存里的時(shí)間太長了,當(dāng)你的程序都跑完了,它還存在那里。這時(shí)它是白白的占用了你的內(nèi)存,累積起來占用的內(nèi)存越來越多……最后就會導(dǎo)致JVM報(bào)錯:out of memory。
2、一般情況下,別人如果能指出你的系統(tǒng)(程序)內(nèi)存溢出,這個人應(yīng)該還是挺厲害的。通常對于新人來說,喜歡把變量直接定義在class下(此時(shí)稱之為實(shí)例變量,或者成員變量),那么在方法里調(diào)用后,這個實(shí)例變量是不會被釋放的,大量的這樣使用就可能會引發(fā)內(nèi)存泄露。
3、把變量定義在方法里,當(dāng)這個方法執(zhí)行完畢后內(nèi)存就得到釋放了,這是個好習(xí)慣。
4、如果想要看到內(nèi)存溢出,可以按這樣的思路去嘗試一下:定義一個靜態(tài)的實(shí)例變量(list或其它集合),然后在一個方法里循環(huán)往這個靜態(tài)變量塞東西,直到這個實(shí)例變量撐爆你的jvm內(nèi)存。很快你就能看到out of memory……
import java.util.ArrayList;
import java.util.List;
public class MemoryTest {
private static List list = new ArrayList();
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
System.out.println("申請前的可用內(nèi)存 = "+getFreeMemory());
while(true){
list.add(new byte[1024*1024]);//用實(shí)例變量申請1M內(nèi)存,當(dāng)方法執(zhí)行完畢時(shí),這個static的變量是不會被釋放
count++;
if (count % 100 == 0) {
System.out.println("當(dāng)前l(fā)ist.size()="+list.size()+",可用內(nèi)存 = "+getFreeMemory());
Thread.sleep(500);
}
}
}
public static long getFreeMemory() {
return Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
大家在進(jìn)行程序系統(tǒng)維護(hù)的時(shí)候是否因?yàn)閖ava編程的內(nèi)存管理問題而無法快速解決導(dǎo)致系統(tǒng)出錯呢?下面我們就一起來了解和學(xué)習(xí)一下,關(guān)于java編程內(nèi)存管理都有哪些知識點(diǎn)。
程序計(jì)數(shù)器(了解)程序計(jì)數(shù)器,可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。
在虛擬機(jī)的概念模型里,字節(jié)碼解釋器工作就是通過改變程序計(jì)數(shù)器的值來選擇下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都要依賴這個計(jì)數(shù)器來完成。
Java虛擬機(jī)棧(了解)Java虛擬機(jī)棧也是線程私有的,它的生命周期與線程相同。
虛擬機(jī)棧描述的是Java方法執(zhí)行的內(nèi)存模型:每個方法在執(zhí)行的同時(shí)都會創(chuàng)建一個棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈表、方法出口信息等。
每一個方法從調(diào)用直至執(zhí)行完成的過程,就對應(yīng)著一個棧幀在虛擬機(jī)棧中入棧到出棧的過程。
局部變量表中存放了編譯器可知的各種基本數(shù)據(jù)類型(boolean、byte、char、short、int、float、long、double)、對象引用和returnAddress類型(指向了一條字節(jié)碼指令的地址)。
如果擴(kuò)展時(shí)無法申請到足夠的內(nèi)存,就會拋出OutOfMemoryError異常。
本地方法棧(了解)本地方法棧與虛擬機(jī)的作用相似,不同之處在于虛擬機(jī)棧為虛擬機(jī)執(zhí)行的Java方法服務(wù),而本地方法棧則為虛擬機(jī)使用到的Native方法服務(wù)。
有的虛擬機(jī)直接把本地方法棧和虛擬機(jī)棧合二為一。
會拋出stackOverflowError和OutOfMemoryError異常。
Java堆堆內(nèi)存用來存放由new創(chuàng)建的對象實(shí)例和數(shù)組。
(重點(diǎn))Java堆是所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時(shí)創(chuàng)建,此內(nèi)存區(qū)域的目的就是存放對象實(shí)例。
Java堆是垃圾收集器管理的主要區(qū)域。
java課程培訓(xùn)機(jī)構(gòu)發(fā)現(xiàn)由于現(xiàn)在收集器基本采用分代回收算法,所以Java堆還可細(xì)分為:新生代和老年代。
從內(nèi)存分配的角度來看,線程共享的Java堆中可能劃分出多個線程私有的分配緩沖區(qū)(TLAB)。