Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),類的實(shí)例(對(duì)象)從中分配空間。Java虛擬機(jī)(JVM)的堆中儲(chǔ)存著正在運(yùn)行的應(yīng)用程序所建立的所有對(duì)象,這些對(duì)象通過new、newarray、anewarray和multianewarray等指令建立,但是它們不需要程序代碼來顯式地釋放。一般來說,堆的是由垃圾回收來負(fù)責(zé)的,盡管JVM規(guī)范并不要求特殊的垃圾回收技術(shù),甚至根本就不需要垃圾回收,但是由于內(nèi)存的有限性,JVM在實(shí)現(xiàn)的時(shí)候都有一個(gè)由垃圾回收所管理的堆。垃圾回收是一種動(dòng)態(tài)存儲(chǔ)管理技術(shù),它自動(dòng)地釋放不再被程序引用的對(duì)象,按照特定的垃圾收集算法來實(shí)現(xiàn)資源自動(dòng)回收的功能。

在水城等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需定制開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)整合營銷推廣,外貿(mào)網(wǎng)站建設(shè),水城網(wǎng)站建設(shè)費(fèi)用合理。
垃圾收集的意義
在C++中,對(duì)象所占的內(nèi)存在程序結(jié)束運(yùn)行之前一直被占用,在明確釋放之前不能分配給其它對(duì)象;而在Java中,當(dāng)沒有對(duì)象引用指向原先分配給某個(gè)對(duì)象的內(nèi)存時(shí),該內(nèi)存便成為垃圾。JVM的一個(gè)系統(tǒng)級(jí)線程會(huì)自動(dòng)釋放該內(nèi)存塊。垃圾收集意味著程序不再需要的對(duì)象是"無用信息",這些信息將被丟棄。當(dāng)一個(gè)對(duì)象不再被引用的時(shí)候,內(nèi)存回收它占領(lǐng)的空間,以便空間被后來的新對(duì)象使用。事實(shí)上,除了釋放沒用的對(duì)象,垃圾收集也可以清除內(nèi)存記錄碎片。由于創(chuàng)建對(duì)象和垃圾收集器釋放丟棄對(duì)象所占的內(nèi)存空間,內(nèi)存會(huì)出現(xiàn)碎片。碎片是分配給對(duì)象的內(nèi)存塊之間的空閑內(nèi)存洞。碎片整理將所占用的堆內(nèi)存移到堆的一端,JVM將整理出的內(nèi)存分配給新的對(duì)象。
垃圾收集能自動(dòng)釋放內(nèi)存空間,減輕編程的負(fù)擔(dān)。這使Java 虛擬機(jī)具有一些優(yōu)點(diǎn)。首先,它能使編程效率提高。在沒有垃圾收集機(jī)制的時(shí)候,可能要花許多時(shí)間來解決一個(gè)難懂的存儲(chǔ)器問題。在用Java語言編程的時(shí)候,靠垃圾收集機(jī)制可大大縮短時(shí)間。其次是它保護(hù)程序的完整性, 垃圾收集是Java語言安全性策略的一個(gè)重要部份。
垃圾收集的一個(gè)潛在的缺點(diǎn)是它的開銷影響程序性能。Java虛擬機(jī)必須追蹤運(yùn)行程序中有用的對(duì)象, 而且最終釋放沒用的對(duì)象。這一個(gè)過程需要花費(fèi)處理器的時(shí)間。其次垃圾收集算法的不完備性,早先采用的某些垃圾收集算法就不能保證100%收集到所有的廢棄內(nèi)存。當(dāng)然隨著垃圾收集算法的不斷改進(jìn)以及軟硬件運(yùn)行效率的不斷提升,這些問題都可以迎刃而解。 (課課家教育java入門到精通)
java中垃圾回收機(jī)制的原理
推薦一篇文章:
對(duì)高性能JAVA代碼之內(nèi)存管理
更甚者你寫的代碼,GC根本就回收不了,直接系統(tǒng)掛掉。GC是一段程序,不是智能,他只回收他認(rèn)為的垃圾,而不是回收你認(rèn)為的垃圾。
GC垃圾回收:
Grabage Collection相信學(xué)過JAVA的人都知道這個(gè)是什么意思。但是他是如何工作的呢?
首先,JVM在管理內(nèi)存的時(shí)候?qū)τ谧兞康墓芾砜偸欠中聦?duì)象和老對(duì)象。新對(duì)象也就是開發(fā)者new出來的對(duì)象,但是由于生命周期短,那么他占用的內(nèi)存并不是馬上釋放,而是被標(biāo)記為老對(duì)象,這個(gè)時(shí)候該對(duì)象還是要存在一段時(shí)間。然后由JVM決定他是否是垃圾對(duì)象,并進(jìn)行回收。
所以我們可以知道,垃圾內(nèi)存并不是用完了馬上就被釋放,所以就會(huì)產(chǎn)生內(nèi)存釋放不及時(shí)的現(xiàn)象,從而降低了內(nèi)存的使用。而當(dāng)程序浩大的時(shí)候。這種現(xiàn)象更為明顯,并且GC的工作也是需要消耗資源的。所以,也就會(huì)產(chǎn)生內(nèi)存浪費(fèi)。
JVM中的對(duì)象生命周期里談內(nèi)存回收:
對(duì)象的生命周期一般分為7個(gè)階段:創(chuàng)建階段,應(yīng)用階段,不可視階段,不可到達(dá)階段,可收集階段,終結(jié)階段,釋放階段。
創(chuàng)建階段:首先大家看一下,如下兩段代碼:
test1:
for( int i=0; i《10000; i++)
Object obj=new Object();
test2:
Object obj=null;
for( int i=0; i《10000; i++)
obj=new Object();
這兩段代碼都是相同的功能,但是顯然test2的性能要比test1性能要好,內(nèi)存使用率要高,這是為什么呢?原因很簡單,test1每次執(zhí)行for循環(huán)都要?jiǎng)?chuàng)建一個(gè)Object的臨時(shí)對(duì)象,但是這些臨時(shí)對(duì)象由于JVM的GC不能馬上銷毀,所以他們還要存在很長時(shí)間,而test2則只是在內(nèi)存中保存一份對(duì)象的引用,而不必創(chuàng)建大量新臨時(shí)變量,從而降低了內(nèi)存的使用。
另外不要對(duì)同一個(gè)對(duì)象初始化多次。例如:
public class A{
private Hashtable table = new Hashtable();
public A(){ table = new Hashtable();
// 這里應(yīng)該去掉,因?yàn)閠able已經(jīng)被初始化。
}
這樣就new了兩個(gè)Hashtable,但是卻只使用了一個(gè)。另外一個(gè)則沒有被引用。而被忽略掉。浪費(fèi)了內(nèi)存。并且由于進(jìn)行了兩次new操作。也影響了代碼的執(zhí)行速度。
應(yīng)用階段:即該對(duì)象至少有一個(gè)引用在維護(hù)他。
不可視階段:即超出該變量的作用域。這里有一個(gè)很好的做法,因?yàn)镴VM在GC的時(shí)候并不是馬上進(jìn)行回收,而是要判斷對(duì)象是否被其他引用在維護(hù)。所以,這個(gè)時(shí)候如果我們在使用完一個(gè)對(duì)象以后對(duì)其obj=null或者obj.doSomething()操作,將其標(biāo)記為空,可以幫助JVM及時(shí)發(fā)現(xiàn)這個(gè)垃圾對(duì)象。
不可到達(dá)階段:就是在JVM中找不到對(duì)該對(duì)象的直接或者間接的引用。
可收集階段,終結(jié)階段,釋放階段:此為回收器發(fā)現(xiàn)該對(duì)象不可到達(dá),finalize方法已經(jīng)被執(zhí)行,或者對(duì)象空間已被重用的時(shí)候。
JAVA的析構(gòu)方法:
可能不會(huì)有人相信,JAVA有析構(gòu)函數(shù)? 是的,有。因?yàn)镴AVA所有類都繼承至Object類,而finalize就是Object類的一個(gè)方法,這個(gè)方法在JAVA中就是類似于C++析構(gòu)函數(shù)。一般來說可以通過重載finalize方法的形式才釋放類中對(duì)象。如:
public class A{
public Object a;
public A(){ a = new Object ;}
protected void finalize() throws java.lang.Throwable{
a = null; // 標(biāo)記為空,釋放對(duì)象
super.finalize(); // 遞歸調(diào)用超類中的finalize方法。
}
}
當(dāng)然,什么時(shí)候該方法被調(diào)用是由JVM來決定的。..。..。..。..。..。..。..。.
一般來說,我們需要?jiǎng)?chuàng)建一個(gè)destory的方法來顯式的調(diào)用該方法。然后在finalize也對(duì)該方法進(jìn)行調(diào)用,實(shí)現(xiàn)雙保險(xiǎn)的做法。
由于對(duì)象的創(chuàng)建是遞歸式的,也就是先調(diào)用超級(jí)類的構(gòu)造,然后依次向下遞歸調(diào)用構(gòu)造函數(shù),所以應(yīng)該避免在類的構(gòu)造函數(shù)中初始化變量,這樣可以避免不必要的創(chuàng)建對(duì)象造成不必要的內(nèi)存消耗。當(dāng)然這里也就看出來接口的優(yōu)勢。
數(shù)組的創(chuàng)建:
由于數(shù)組需要給定一個(gè)長度,所以在不確定數(shù)據(jù)數(shù)量的時(shí)候經(jīng)常會(huì)創(chuàng)建過大,或過小的數(shù)組的現(xiàn)象。造成不必要的內(nèi)存浪費(fèi),所以可以通過軟引用的方式來告訴JVM及時(shí)回收該內(nèi)存。(軟引用,具體查資料)。
例如:
Object obj = new char[10000000000000000];
SoftReference ref = new SoftReference(obj);
共享靜態(tài)存儲(chǔ)空間:
我們都知道靜態(tài)變量在程序運(yùn)行期間其內(nèi)存是共享的,因此有時(shí)候?yàn)榱斯?jié)約內(nèi)存工件,將一些變量聲明為靜態(tài)變量確實(shí)可以起到節(jié)約內(nèi)存空間的作用。但是由于靜態(tài)變量生命周期很長,不易被系統(tǒng)回收,所以使用靜態(tài)變量要合理,不能盲目的使用。以免適得其反。
因此建議在下面情況下使用:
1,變量所包含的對(duì)象體積較大,占用內(nèi)存過多。
2,變量所包含對(duì)象生命周期較長。
3,變量所包含數(shù)據(jù)穩(wěn)定。
4,該類的對(duì)象實(shí)例有對(duì)該變量所包含的對(duì)象的共享需求。(也就是說是否需要作為全局變量)。
對(duì)象重用與GC:
有的時(shí)候,如數(shù)據(jù)庫操作對(duì)象,一般情況下我們都需要在各個(gè)不同模塊間使用,所以這樣的對(duì)象需要進(jìn)行重用以提高性能。也有效的避免了反復(fù)創(chuàng)建對(duì)象引起的性能下降。
一般來說對(duì)象池是一個(gè)不錯(cuò)的注意。如下:
public abstarct class ObjectPool{
private Hashtable locked,unlocked;
private long expirationTime;
abstract Object create();
abstract void expire( Object o);
abstract void validate( Object o);
synchronized Object getObject(){。..};
synchronized void freeObject(Object o){。..};
這樣我們就完成了一個(gè)對(duì)象池,我們可以將通過對(duì)應(yīng)的方法來存取刪除所需對(duì)象。來維護(hù)這快內(nèi)存提高內(nèi)存重用。
當(dāng)然也可以通過調(diào)用System.gc()強(qiáng)制系統(tǒng)進(jìn)行垃圾回收操作。當(dāng)然這樣的代價(jià)是需要消耗一些cpu資源。
不要提前創(chuàng)建對(duì)象:
盡量在需要的時(shí)候創(chuàng)建對(duì)象,重復(fù)的分配,構(gòu)造對(duì)象可能會(huì)因?yàn)槔厥兆鲱~外的工作降低性能。
JVM內(nèi)存參數(shù)調(diào)優(yōu):
強(qiáng)制內(nèi)存回收對(duì)于系統(tǒng)自動(dòng)的內(nèi)存回收機(jī)制會(huì)產(chǎn)生負(fù)面影響,會(huì)加大系統(tǒng)自動(dòng)回收的處理時(shí)間,所以應(yīng)該盡量避免顯式使用System.gc(),
JVM的設(shè)置可以提高系統(tǒng)的性能。例如:
java -XX:NewSize=128m -XX:MaxNewSize=128m -XX:SurvivorRatio=8 -Xms512m -Xmx512m
具體可以查看java幫助文檔。我們主要介紹程序設(shè)計(jì)方面的性能提高。
JAVA程序設(shè)計(jì)中有關(guān)內(nèi)存管理的其他經(jīng)驗(yàn):
根據(jù)JVM內(nèi)存管理的工作原理,可以通過一些技巧和方式讓JVM做GC處理時(shí)更加有效。,從而提高內(nèi)存使用和縮短GC的執(zhí)行時(shí)間。
1,盡早釋放無用對(duì)象的引用。即在不使用對(duì)象的引用后設(shè)置為空,可以加速GC的工作。(當(dāng)然如果是返回值。..。.)
2,盡量少用finalize函數(shù),此函數(shù)是JAVA給程序員提供的一個(gè)釋放對(duì)象或資源的機(jī)會(huì),但是卻會(huì)加大GC工作量。
3,如果需要使用到圖片,可以使用soft應(yīng)用類型,它可以盡可能將圖片讀入內(nèi)存而不引起OutOfMemory.
4,注意集合數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),往往數(shù)據(jù)結(jié)構(gòu)越復(fù)雜,GC工作量更大,處理更復(fù)雜。
5,盡量避免在默認(rèn)構(gòu)造器(構(gòu)造函數(shù))中創(chuàng)建,初始化大量的對(duì)象。
6,盡量避免強(qiáng)制系統(tǒng)做垃圾回收。會(huì)增加系統(tǒng)做垃圾回收的最終時(shí)間降低性能。
7,盡量避免顯式申請數(shù)組,如果不得不申請數(shù)組的話,要盡量準(zhǔn)確估算數(shù)組大小。
8,如果在做遠(yuǎn)程方法調(diào)用。要盡量減少傳遞的對(duì)象大小。或者使用瞬間值避免不必要數(shù)據(jù)的傳遞。
9,盡量在合適的情況下使用對(duì)象池來提高系統(tǒng)性能減少內(nèi)存開銷,當(dāng)然,對(duì)象池不能過于龐大,會(huì)適得其反.
不對(duì),java雖然有垃圾回收機(jī)制,但是不能在指定的時(shí)間釋放內(nèi)存對(duì)象,只能在程序運(yùn)行期間,當(dāng)虛擬機(jī)空閑的時(shí)候回收。
Java的垃圾回收機(jī)制是Java虛擬機(jī)提供的能力,用于在空閑時(shí)間以不定時(shí)的方式動(dòng)態(tài)回收無任何引用的對(duì)象占據(jù)的內(nèi)存空間。
需要注意的是:垃圾回收回收的是無任何引用的對(duì)象占據(jù)的內(nèi)存空間而不是對(duì)象本身,70%以上的人回答的含義是回收對(duì)象,實(shí)際上這是不正確的。
System.gc()
Runtime.getRuntime().gc()
上面的方法調(diào)用時(shí)用于顯式通知JVM可以進(jìn)行一次垃圾回收,但真正垃圾回收機(jī)制具體在什么時(shí)間點(diǎn)開始發(fā)生動(dòng)作這同樣是不可預(yù)料的,這和搶占式的線程在發(fā)生作用時(shí)的原理一樣。
用System.gc()就可以
運(yùn)行垃圾回收器。
調(diào)用 gc 方法暗示著 Java 虛擬機(jī)做了一些努力來回收未用對(duì)象,以便能夠快速地重用這些對(duì)象當(dāng)前占用的內(nèi)存。當(dāng)控制權(quán)從方法調(diào)用中返回時(shí),虛擬機(jī)已經(jīng)盡最大努力從所有丟棄的對(duì)象中回收了空間。
調(diào)用 System.gc() 實(shí)際上等效于調(diào)用:
Runtime.getRuntime().gc()
垃圾回收就是gc(gabage collection)。
java比c++的優(yōu)點(diǎn)就是多了垃圾回收機(jī)制,程序員不用去關(guān)心垃圾的回收,系統(tǒng)會(huì)自動(dòng)調(diào)用去回收內(nèi)存。
一般我們想回收的時(shí)候只需要調(diào)用system.gc方法就可以了。系統(tǒng)會(huì)自己去調(diào)用destroy方法和其他的回收方法釋放內(nèi)存,節(jié)省內(nèi)存空間。
垃圾回收目的:Java語言中一個(gè)顯著的特點(diǎn)就是引入了垃圾回收機(jī)制,使c++程序員最頭疼的內(nèi)存管理的問題迎刃而解,它使得Java程序員在編寫程序的時(shí)候不再需要考慮內(nèi)存管理。
由于有個(gè)垃圾回收機(jī)制,Java中的對(duì)象不再有“作用域”的概念,只有對(duì)象的引用才有“作用域”。垃圾回收可以有效的防止內(nèi)存泄露,有效的使用空閑的內(nèi)存。
當(dāng)前題目:java代碼觸發(fā)垃圾回收 java 手動(dòng)垃圾回收
文章起源:http://chinadenli.net/article30/doojhso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、外貿(mào)建站、微信小程序、網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容