在Java中微宝,內(nèi)存泄漏就是存在一些被分配的對象棺亭,這些對象有下面兩個特點(diǎn),首先芥吟,這些對象是可達(dá)的侦铜,即在有向圖中,存在通路可以與其相連钟鸵;其次钉稍,這些對象是無用的,即程序以后不會再使用這些對象棺耍。如果對象滿足這兩個條件贡未,這些對象就可以判定為Java中的內(nèi)存泄漏,這些對象不會被GC所回收,然而它卻占用內(nèi)存俊卤。
在C++中嫩挤,內(nèi)存泄漏的范圍更大一些。有些對象被分配了內(nèi)存空間消恍,然后卻不可達(dá)岂昭,由于C++中沒有GC,這些內(nèi)存將永遠(yuǎn)收不回來狠怨。在Java中约啊,這些不可達(dá)的對象都由GC負(fù)責(zé)回收,因此程序員不需要考慮這部分的內(nèi)存泄露佣赖。
通過分析恰矩,我們得知,對于C++憎蛤,程序員需要自己管理邊和頂點(diǎn)外傅,而對于Java程序員只需要管理邊就可以了(不需要管理頂點(diǎn)的釋放)。通過這種方式俩檬,Java提高了編程的效率萎胰。
因此,通過以上分析棚辽,我們知道在Java中也有內(nèi)存泄漏奥洼,但范圍比C++要小一些。因為Java從語言上保證晚胡,任何對象都是可達(dá)的灵奖,所有的不可達(dá)對象都由GC管理。
因此估盘,通過以上分析瓷患,我們知道在Java中也有內(nèi)存泄漏,但范圍比C++要小一些遣妥。因為Java從語言上保證擅编,任何對象都是可達(dá)的,所有的不可達(dá)對象都由GC管理箫踩。
對于程序員來說爱态,GC基本是透明的,不可見的境钟。雖然锦担,我們只有幾個函數(shù)可以訪問GC,例如運(yùn)行GC的函數(shù)System.gc()慨削,但是根據(jù)Java語言規(guī)范定義洞渔, 該函數(shù)不保證JVM的垃圾收集器一定會執(zhí)行套媚。因為,不同的JVM實現(xiàn)者可能使用不同的算法管理GC磁椒。通常堤瘤,GC的線程的優(yōu)先級別較低。JVM調(diào)用GC的策略也有很多種浆熔,有的是內(nèi)存使用到達(dá)一定程度時本辐,GC才開始工作,也有定時執(zhí)行的医增,有的是平緩執(zhí)行GC师郑,有的是中斷式執(zhí)行GC。但通常來說调窍,我們不需要關(guān)心這些。除非在一些特定的場合张遭,GC的執(zhí)行影響應(yīng)用程序的性能邓萨,例如對于基于Web的實時系統(tǒng),如網(wǎng)絡(luò)游戲等菊卷,用戶不希望GC突然中斷應(yīng)用程序執(zhí)行而進(jìn)行垃圾回收缔恳,那么我們需要調(diào)整GC的參數(shù),讓GC能夠通過平緩的方式釋放內(nèi)存洁闰,例如將垃圾回收分解為一系列的小步驟執(zhí)行歉甚,Sun提供的HotSpot JVM就支持這一特性。
下面給出了一個簡單的內(nèi)存泄露的例子扑眉。在這個例子中纸泄,我們循環(huán)申請Object對象,并將所申請的對象放入一個Vector中腰素,如果我們僅僅釋放引用本身聘裁,那么Vector仍然引用該對象,所以這個對象對GC來說是不可回收的弓千。因此衡便,如果對象加入到Vector后,還必須從Vector中刪除洋访,最簡單的方法就是將Vector對象設(shè)置為null镣陕。
Vector v=new Vector(10);
for (int i=1;i<100; i++)
{
Object o=new Object();
v.add(o);
o=null;
}
此時,所有的Object對象都沒有被釋放姻政,因為變量v引用這些對象呆抑。