自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高性能JAVA代碼之_內(nèi)存管理

開發(fā) 后端
雖然JAVA的GC已經(jīng)替開發(fā)者完成了對(duì)內(nèi)存的管理,但GC不是萬(wàn)能的,很多人寫的工程里依然出現(xiàn)OutOfMemory,所以如果JAVA的開發(fā)人員不注意內(nèi)存的使用,依然會(huì)造成較高的內(nèi)存消耗,從而性能很低。

更甚者你寫的代碼,GC根本就回收不了,直接系統(tǒng)掛掉。GC是一段程序,不是智能,他只回收他認(rèn)為的垃圾,而不是回收你認(rèn)為的垃圾。

GC垃圾回收:

Grabage Collection相信學(xué)過(guò)JAVA的人都知道這個(gè)是什么意思.但是他是如何工作的呢?

首先,JVM在管理內(nèi)存的時(shí)候?qū)τ谧兞康墓芾砜偸欠中聦?duì)象和老對(duì)象。新對(duì)象也就是開發(fā)者new出來(lái)的對(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:

 

  1. forint i=0; i<10000; i++)  
  2.  
  3. Object obj=new Object();  

 

test2:

 

  1. Object obj=null;  
  2.  
  3. forint i=0; i<10000; i++)  
  4.  
  5. obj=new Object();  

 

這兩段代碼都是相同的功能,但是顯然test2的性能要比test1性能要好,內(nèi)存使用率要高,這是為什么呢?原因很簡(jiǎn)單,test1每次執(zhí)行for循環(huán)都要?jiǎng)?chuàng)建一個(gè)Object的臨時(shí)對(duì)象,但是這些臨時(shí)對(duì)象由于JVM的GC不能馬上銷毀,所以他們還要存在很長(zhǎng)時(shí)間,而test2則只是在內(nèi)存中保存一份對(duì)象的引用,而不必創(chuàng)建大量新臨時(shí)變量,從而降低了內(nèi)存的使用。

另外不要對(duì)同一個(gè)對(duì)象初始化多次。例如:

 

  1. public class A{  
  2.  
  3. private Hashtable table = new Hashtable();  
  4.  
  5. public A(){  
  6.  
  7. table = new Hashtable(); // 這里應(yīng)該去掉,因?yàn)閠able已經(jīng)被初始化.  
  8.  
  9. }  
  10.  
  11. }  

 

這樣就new了兩個(gè)Hashtable,但是卻只使用了一個(gè)。另外一個(gè)則沒(méi)有被引用.而被忽略掉.浪費(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í)候如果我們?cè)谑褂猛暌粋€(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ù).一般來(lái)說(shuō)可以通過(guò)重載finalize方法的形式才釋放類中對(duì)象.如:

 

  1. public class A{  
  2.  
  3. public Object a;  
  4.  
  5. public A(){ a = new Object ;}  
  6.  
  7. protected void finalize() throws java.lang.Throwable{  
  8.  
  9. a = null// 標(biāo)記為空,釋放對(duì)象  
  10.  
  11. super.finalize(); // 遞歸調(diào)用超類中的finalize方法.  
  12.  
  13. }  
  14.  
  15. }  

 

當(dāng)然,什么時(shí)候該方法被調(diào)用是由JVM來(lái)決定的.......................

一般來(lái)說(shuō),我們需要?jiǎng)?chuàng)建一個(gè)destory的方法來(lái)顯式的調(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)然這里也就看出來(lái)接口的優(yōu)勢(shì).

數(shù)組的創(chuàng)建:

由于數(shù)組需要給定一個(gè)長(zhǎng)度,所以在不確定數(shù)據(jù)數(shù)量的時(shí)候經(jīng)常會(huì)創(chuàng)建過(guò)大,或過(guò)小的數(shù)組的現(xiàn)象.造成不必要的內(nèi)存浪費(fèi),所以可以通過(guò)軟引用的方式來(lái)告訴JVM及時(shí)回收該內(nèi)存.(軟引用,具體查資料).

例如:

 

  1. Object obj = new char[10000000000000000];  
  2.  
  3. 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)變量生命周期很長(zhǎng),不易被系統(tǒng)回收,所以使用靜態(tài)變量要合理,不能盲目的使用.以免適得其反。

因此建議在下面情況下使用:

1,變量所包含的對(duì)象體積較大,占用內(nèi)存過(guò)多.

2,變量所包含對(duì)象生命周期較長(zhǎng).

3,變量所包含數(shù)據(jù)穩(wěn)定.

4,該類的對(duì)象實(shí)例有對(duì)該變量所包含的對(duì)象的共享需求.(也就是說(shuō)是否需要作為全局變量).

對(duì)象重用與GC:

有的時(shí)候,如數(shù)據(jù)庫(kù)操作對(duì)象,一般情況下我們都需要在各個(gè)不同模塊間使用,所以這樣的對(duì)象需要進(jìn)行重用以提高性能.也有效的避免了反復(fù)創(chuàng)建對(duì)象引起的性能下降.

一般來(lái)說(shuō)對(duì)象池是一個(gè)不錯(cuò)的注意.如下:

 

  1. public abstarct class ObjectPool{  
  2.  
  3. private Hashtable locked,unlocked;  
  4.  
  5. private long expirationTime;  
  6.  
  7. abstract Object create();  
  8.  
  9. abstract void expire( Object o);  
  10.  
  11. abstract void validate( Object o);  
  12.  
  13. synchronized Object getObject(){...};  
  14.  
  15. synchronized void freeObject(Object o){...};  
  16.  
  17. }  
  18.  

 

這樣我們就完成了一個(gè)對(duì)象池,我們可以將通過(guò)對(duì)應(yīng)的方法來(lái)存取刪除所需對(duì)象.來(lái)維護(hù)這快內(nèi)存提高內(nèi)存重用.

當(dāng)然也可以通過(guò)調(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)存管理的工作原理,可以通過(guò)一些技巧和方式讓JVM做GC處理時(shí)更加有效.,從而提高內(nèi)存使用和縮短GC的執(zhí)行時(shí)間.

1,盡早釋放無(wú)用對(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,盡量避免顯式申請(qǐng)數(shù)組,如果不得不申請(qǐng)數(shù)組的話,要盡量準(zhǔn)確估算數(shù)組大小.

8,如果在做遠(yuǎn)程方法調(diào)用.要盡量減少傳遞的對(duì)象大小.或者使用瞬間值避免不必要數(shù)據(jù)的傳遞.

9,盡量在合適的情況下使用對(duì)象池來(lái)提高系統(tǒng)性能減少內(nèi)存開銷,當(dāng)然,對(duì)象池不能過(guò)于龐大,會(huì)適得其反.

【編輯推薦】

  1. 全面解析Java的垃圾回收機(jī)制
  2. 你不知道的5個(gè)JVM命令行標(biāo)志
  3. Eclipse中進(jìn)行JVM內(nèi)存設(shè)置
  4. 解析JVM和JIT診斷技術(shù)的用法 
責(zé)任編輯:金賀 來(lái)源: ITEYE博客
相關(guān)推薦

2011-04-25 14:06:23

java

2024-03-20 08:00:00

軟件開發(fā)Java編程語(yǔ)言

2023-02-20 15:27:30

開發(fā)JavaScript內(nèi)存管理

2019-12-31 10:33:57

Netty高性能內(nèi)存

2018-01-12 14:37:34

Java代碼實(shí)踐

2022-12-09 08:40:56

高性能內(nèi)存隊(duì)列

2012-12-17 13:51:22

Web前端JavaScriptJS

2011-04-18 10:16:30

WEB高性能

2023-10-31 18:52:29

網(wǎng)絡(luò)框架XDP技術(shù)

2009-06-24 15:00:39

Javascript代

2014-04-25 09:02:17

LuaLua優(yōu)化Lua代碼

2023-09-18 09:10:11

Golang高性能緩存庫(kù)

2011-04-19 11:06:03

JavaScriptweb

2023-11-01 11:51:08

Linux性能優(yōu)化

2011-10-18 13:58:32

高性能web

2011-04-07 13:53:25

Web工具

2015-12-17 13:19:29

編寫高性能Swift

2011-02-23 09:49:40

ASP.NET

2011-04-27 10:57:29

高性能web開發(fā)

2011-04-07 13:39:24

WebHTTP
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)