日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 终结此段代码并重新运行_Java垃圾回收

發布時間:2023/12/10 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 终结此段代码并重新运行_Java垃圾回收 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

好久沒看關于java的書了, 最近, 看了James Gosling的<>, 做了一些讀書筆記. 這部分是關于垃圾回收的.

1.垃圾回收

對象是使用new創建的, 但是并沒有與之相對應的delete操作來回收對象占用的內存. 當我們完成對某個對象的使用時, 只需停止該對象的引用:

->將引用改變為指向其他對象

->將引用指向null

->從方法中返回, 使得該方法的局部變量不復存在

要點:

->當我們從任何可執行代碼都無法到達某個對象時, 它所占用的空間就可以被回收.

->垃圾回收意味著我們永遠不用擔心出現虛懸引用(dangling reference). 虛懸引用, 指得是引用已經被刪除的內存空間. 在那些程序員可以直接控制何時刪除對象的系統中, 會存在這樣的問題.

->垃圾回收器模型: 引用計數器法(不能解決循環引用), 標記-清除(mark-and-sweep)

2.終結

finalize方法

->在垃圾回收器確定該對象是不可達的且該對象的空間將被回收之后, 垃圾回收器就會調用這個方法.

->這個方法可以清除該對象所使用的所有非內存資源, 對每一個對象最多只能調用一次, 即使在這個方法的執行使得該對象重新變為可達之后又馬上會再次變為不可達的情況下, 該方法也只能調用一次.

->finalize方法可以在任何特定的時間段內被調用, 它也可能永遠不會被調用(java虛擬機結束).

覆寫finalize方法

->當一個對象變成垃圾時, 它所引用的其他對象也很有可能會變成垃圾. 這些垃圾可能在調用我們編寫的finalize方法之前就已經被終結了, 因此它們可能處于不可預知的狀態.

->覆寫finalize方法是, 加上super.finalize方法. 最好加在finally字句里面.保證其超類中聲明的部分內容也可以被終結.

3.與垃圾回收器交互的相關類和方法

類: Runtime.getRuntime(), System

方法:gc(), runFinalization(), freeMemory(), totalMemory(), maxMemory()

System類支持靜態的gc()和runFinalization()方法, 它們將調用當前Runtime對象上的相應方法.

4.可達性狀態和引用對象

對象只有在沒有任何引用指定它的時候才可以被當作垃圾回收, 但有時我們可能希望在仍舊有選定引用指向對象時, 將該對象作為垃圾回收掉.

引用對象的唯一用途就是維護對另一個被稱為指稱物(referent)的對象的引用. 通常我們通過字段或者局部變量來維護對對象的引用, 但是現在我們可以維護對引用對象的直接引用, 而該引用對象包裝了我們實際需要的對象. 垃圾回收器可能判斷出對某個對象的殘留引用是否都是經由引用對象面引用到該對象的, 因此它可以決定是否要回收該對象. 引用對象的強度將決定垃圾回收器的行為, 普通的引用都是強度最大的引用.

Reference類

->包:java.lang.ref

->典型方法: get(), clear(), enqueue(), isEnqueued()

引用和可達性強度

->對象是強可達的(strongly reachable):普通的引用

->對象是軟可達的(softly reachable):SoftReference

->對象是弱可達的(weakly reachable):WeakReference

->對象是虛可達的(phantom reachable):PhantomReference

->對象是不可達的:沒有引用鏈接

一旦對象變為弱可達的(或者列弱), 它就可以被終結. 如果在終結之后該對象是不可達的, 那么它就可以被回收了.

對象可達性階段會觸發垃圾回收器對相關的引用對象類型做出適當的行為:

->軟可達對象可能會任憑垃圾回收器去回收. 我們可確定的是所有對軟可達對象的SoftReference都會在拋出outofMemoryError錯誤這前被清除.

->弱可達對象將會被垃圾回收器回收.

->虛可達對象并不是真正意義上的可達, 因為無法通過PhantomReference訪問其指稱對象, 其get方法總是返回null. 但是虛引用的存在可以防止對象在顯式清除虛引用之前被回收. 虛引用使我們可以處理那些finalize方法已經被調用過的對象, 從而可以安全地認為它們是"死"的.

經過一個晚上的努力終于完成了一個文件替換指定字符串的程序,

但是由于我要替換的全站程序html文件太多,

所以eclipse下邊老是在一個目錄結束后報出java.lang.OutOfMemoryError: Java heap space的異常,然后就崩潰了。

我一想肯定是頻繁操作造成來不及回收,

于是在每個循環之后加上一個Thread.sleep(1000),

發現還是到那個目錄下就死掉,于是把1000改成5000,還是到那里死掉,

我想可能不是來不及回收這么簡單,或許sun 的JVM里邊剛好對于這種情況不釋放也有可能。

接著我又把啟動的參數添上一個 -Xmx256M,這回就可以了。

想一想,還是對于垃圾回收的原理不太了解,就在網上查了一下,發現了幾篇不錯的文章。

還有:Java堆的管理—垃圾回收提到一下幾點,很不錯,或許可以作為寫程序時候的準則:

(1)不要試圖去假定垃圾收集發生的時間,這一切都是未知的。

比如,方法中的一個臨時對象在方法調用完畢后就變成了無用對象,這個時候它的內存就可以被釋放。

(2)Java中提供了一些和垃圾收集打交道的類,

而且提供了一種強行執行垃圾收集的方法--調用System.gc(),

但這同樣是個不確定的方法。Java 中并不保證每次調用該方法就一定能夠啟動垃圾收集,

它只不過會向JVM發出這樣一個申請,到底是否真正執行垃圾收集,一切都是個未知數。

(3)挑選適合自己的垃圾收集器。一般來說,如果系統沒有特殊和苛刻的性能要求,

可以采用JVM的缺省選項。否則可以考慮使用有針對性的垃圾收集器,

比如增量收集器就比較適合實時性要求較高的系統之中。

系統具有較高的配置,有比較多的閑置資源,可以考慮使用并行標記/清除收集器。

(4)關鍵的也是難把握的問題是內存泄漏。

良好的編程習慣和嚴謹的編程態度永遠是最重要的,不要讓自己的一個小錯誤導致內存出現大漏洞。

(5)盡早釋放無用對象的引用。

大多數程序員在使用臨時變量的時候,

都是讓引用變量在退出活動域(scope)后,自動設置為null,

暗示垃圾收集器來收集該對象,還必須注意該引用的對象是否被監聽,如果有,則要去掉監聽器,然后再賦空值。

就是說,對于頻繁申請內存和釋放內存的操作,還是自己控制一下比較好,

但是System.gc()的方法不一定適用,最好使用finallize強制執行或者寫自己的finallize方法。

gc即垃圾收集機制是指jvm用于釋放那些不再使用的對象所占用的內存。java語言并不要求jvm有gc,也沒有規定gc如何工作。不過常用的jvm都有gc,而且大多數gc都使用類似的算法管理內存和執行收集操作。

在充分理解了垃圾收集算法和執行過程后,才能有效的優化它的性能。有些垃圾收集專用于特殊的應用程序。比如,實時應用程序主要是為了避免垃圾收集中斷,而大多數OLTP應用程序則注重整體效率。理解了應用程序的工作負荷和jvm支持的垃圾收集算法,便可以進行優化配置垃圾收集器。

垃圾收集的目的在于清除不再使用的對象。gc通過確定對象是否被活動對象引用來確定是否收集該對象。gc首先要判斷該對象是否是時候可以收集。兩種常用的方法是引用計數和對象引用遍歷。

1.1.引用計數

引用計數存儲對特定對象的所有引用數,也就是說,當應用程序創建引用以及引用超出范圍時,jvm必須適當增減引用數。當某對象的引用數為0時,便可以進行垃圾收集。

1.2.對象引用遍歷

早期的jvm使用引用計數,現在大多數jvm采用對象引用遍歷。對象引用遍歷從一組對象開始,沿著整個對象圖上的每條鏈接,遞歸確定可到達(reachable)的對象。如果某對象不能從這些根對象的一個(至少一個)到達,則將它作為垃圾收集。在對象遍歷階段,gc必須記住哪些對象可以到達,以便刪除不可到達的對象,這稱為標記(marking)對象。

下一步,gc要刪除不可到達的對象。刪除時,有些gc只是簡單的掃描堆棧,刪除未標記的未標記的對象,并釋放它們的內存以生成新的對象,這叫做清除(sweeping)。這種方法的問題在于內存會分成好多小段,而它們不足以用于新的對象,但是組合起來卻很大。因此,許多gc可以重新組織內存中的對象,并進行壓縮(compact),形成可利用的空間。

為此,gc需要停止其他的活動活動。這種方法意味著所有與應用程序相關的工作停止,只有gc運行。結果,在響應期間增減了許多混雜請求。另外,更復雜的 gc不斷增加或同時運行以減少或者清除應用程序的中斷。有的gc使用單線程完成這項工作,有的則采用多線程以增加效率。

2.幾種垃圾回收機制

2.1.標記-清除收集器

這種收集器首先遍歷對象圖并標記可到達的對象,然后掃描堆棧以尋找未標記對象并釋放它們的內存。這種收集器一般使用單線程工作并停止其他操作。

2.2.標記-壓縮收集器

有時也叫標記-清除-壓縮收集器,與標記-清除收集器有相同的標記階段。在第二階段,則把標記對象復制到堆棧的新域中以便壓縮堆棧。這種收集器也停止其他操作。

2.3.復制收集器

這種收集器將堆棧分為兩個域,常稱為半空間。每次僅使用一半的空間,jvm生成的新對象則放在另一半空間中。gc運行時,它把可到達對象復制到另一半空間,從而壓縮了堆棧。這種方法適用于短生存期的對象,持續復制長生存期的對象則導致效率降低。

2.4.增量收集器

增量收集器把堆棧分為多個域,每次僅從一個域收集垃圾。這會造成較小的應用程序中斷。

2.5.分代收集器

這種收集器把堆棧分為兩個或多個域,用以存放不同壽命的對象。jvm生成的新對象一般放在其中的某個域中。過一段時間,繼續存在的對象將獲得使用期并轉入更長壽命的域中。分代收集器對不同的域使用不同的算法以優化性能。

2.6.并發收集器

并發收集器與應用程序同時運行。這些收集器在某點上(比如壓縮時)一般都不得不停止其他操作以完成特定的任務,但是因為其他應用程序可進行其他的后臺操作,所以中斷其他處理的實際時間大大降低。

2.7.并行收集器

并行收集器使用某種傳統的算法并使用多線程并行的執行它們的工作。在多cpu機器上使用多線程技術可以顯著的提高java應用程序的可擴展性。

3.Sun HotSpot

1.4.1 JVM堆大小的調整

Sun HotSpot 1.4.1使用分代收集器,它把堆分為三個主要的域:新域、舊域以及永久域。Jvm生成的所有新對象放在新域中。一旦對象經歷了一定數量的垃圾收集循環后,便獲得使用期并進入舊域。在永久域中jvm則存儲class和method對象。就配置而言,永久域是一個獨立域并且不認為是堆的一部分。

下面介紹如何控制這些域的大小。可使用-Xms和-Xmx 控制整個堆的原始大小或最大值。

下面的命令是把初始大小設置為128M:

java –Xms128m

–Xmx256m為控制新域的大小,可使用-XX:NewRatio設置新域在堆中所占的比例。

下面的命令把整個堆設置成128m,新域比率設置成3,即新域與舊域比例為1:3,新域為堆的1/4或32M:

java –Xms128m –Xmx128m

–XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize設置新域的初始值和最大值。

下面的命令把新域的初始值和最大值設置成64m:

java –Xms256m –Xmx256m –Xmn64m

永久域默認大小為4m。運行程序時,jvm會調整永久域的大小以滿足需要。每次調整時,jvm會對堆進行一次完全的垃圾收集。

使用-XX:MaxPerSize標志來增加永久域搭大小。在WebLogic Server應用程序加載較多類時,經常需要增加永久域的最大值。當jvm加載類時,永久域中的對象急劇增加,從而使jvm不斷調整永久域大小。為了避免調整,可使用-XX:PerSize標志設置初始值。

下面把永久域初始值設置成32m,最大值設置成64m。

java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m

默認狀態下,HotSpot在新域中使用復制收集器。該域一般分為三個部分。第一部分為Eden,用于生成新的對象。另兩部分稱為救助空間,當Eden 充滿時,收集器停止應用程序,把所有可到達對象復制到當前的from救助空間,一旦當前的from救助空間充滿,收集器則把可到達對象復制到當前的to救助空間。From和to救助空間互換角色。維持活動的對象將在救助空間不斷復制,直到它們獲得使用期并轉入舊域。使用-XX:SurvivorRatio 可控制新域子空間的大小。

同NewRation一樣,SurvivorRation規定某救助域與Eden空間的比值。比如,以下命令把新域設置成64m,Eden占32m,每個救助域各占16m:

java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2

如前所述,默認狀態下HotSpot對新域使用復制收集器,對舊域使用標記-清除-壓縮收集器。在新域中使用復制收集器有很多意義,因為應用程序生成的大部分對象是短壽命的。理想狀態下,所有過渡對象在移出Eden空間時將被收集。如果能夠這樣的話,并且移出Eden空間的對象是長壽命的,那么理論上可以立即把它們移進舊域,避免在救助空間反復復制。但是,應用程序不能適合這種理想狀態,因為它們有一小部分中長壽命的對象。最好是保持這些中長壽命的對象并放在新域中,因為復制小部分的對象總比壓縮舊域廉價。為控制新域中對象的復制,可用-XX:TargetSurvivorRatio控制救助空間的比例(該值是設置救助空間的使用比例。如救助空間位1M,該值50表示可用500K)。該值是一個百分比,默認值是50。當較大的堆棧使用較低的 sruvivorratio時,應增加該值到80至90,以更好利用救助空間。用-XX:maxtenuring threshold可控制上限。

為放置所有的復制全部發生以及希望對象從eden擴展到舊域,可以把MaxTenuring Threshold設置成0。設置完成后,實際上就不再使用救助空間了,因此應把SurvivorRatio設成最大值以最大化Eden空間,設置如下:

java … -XX:MaxTenuringThreshold=0 –XX:SurvivorRatio=50000 …

4.BEA JRockit JVM的使用

Bea WebLogic 8.1使用的新的JVM用于Intel平臺。在Bea安裝完畢的目錄下可以看到有一個類似于jrockit81sp1_141_03的文件夾。這就是 Bea新JVM所在目錄。不同于HotSpot把Java字節碼編譯成本地碼,它預先編譯成類。JRockit還提供了更細致的功能用以觀察JVM的運行狀態,主要是獨立的GUI控制臺(只能適用于使用Jrockit才能使用jrockit81sp1_141_03自帶的console監控一些cpu及 memory參數)或者WebLogic Server控制臺。

Bea JRockit JVM支持4種垃圾收集器:

4.1.1.分代復制收集器

它與默認的分代收集器工作策略類似。對象在新域中分配,即JRockit文檔中的nursery。這種收集器最適合單cpu機上小型堆操作。

4.1.2.單空間并發收集器

該收集器使用完整堆,并與背景線程共同工作。盡管這種收集器可以消除中斷,但是收集器需花費較長的時間尋找死對象,而且處理應用程序時收集器經常運行。如果處理器不能應付應用程序產生的垃圾,它會中斷應用程序并關閉收集。

分代并發收集器這種收集器在護理域使用排它復制收集器,在舊域中則使用并發收集器。由于它比單空間共同發生收集器中斷頻繁,因此它需要較少的內存,應用程序的運行效率也較高,注意,過小的護理域可以導致大量的臨時對象被擴展到舊域中。這會造成收集器超負荷運作,甚至采用排它性工作方式完成收集。

4.1.3.并行收集器

該收集器也停止其他進程的工作,但使用多線程以加速收集進程。盡管它比其他的收集器易于引起長時間的中斷,但一般能更好的利用內存,程序效率也較高。

默認狀態下,JRockit使用分代并發收集器。要改變收集器,可使用-Xgc:,對應四個收集器分別為 gencopy,singlecon,gencon以及parallel。可使用-Xms和-Xmx設置堆的初始大小和最大值。要設置護理域,則使用- Xns:java –jrockit –Xms512m –Xmx512m –Xgc:gencon –Xns128m…盡管JRockit支持-verbose:gc開關,但它輸出的信息會因收集器的不同而異。JRockit還支持memory、 load和codegen的輸出。

注意 :如果 使用JRockit JVM的話還可以使用WLS自帶的console(C:\bea\jrockit81sp1_141_03\bin下)來監控一些數據,如cpu, memery等。要想能構監控必須在啟動服務時startWeblogic.cmd中加入-Xmanagement參數。

5.如何從JVM中獲取信息來進行調整

-verbose.gc開關可顯示gc的操作內容。打開它,可以顯示最忙和最空閑收集行為發生的時間、收集前后的內存大小、收集需要的時間等。打開- xx:+ printgcdetails開關,可以詳細了解gc中的變化。打開-XX: + PrintGCTimeStamps開關,可以了解這些垃圾收集發生的時間,自jvm啟動以后以秒計量。最后,通過-xx: + PrintHeapAtGC開關了解堆的更詳細的信息。為了了解新域的情況,可以通過-XX:=PrintTenuringDistribution開關了解獲得使用期的對象權。

6.Pdm系統JVM調整

6.1.服務器:前提內存1G 單CPU

可通過如下參數進行調整:-server 啟用服務器模式(如果CPU多,服務器機建議使用此項)

-Xms,-Xmx一般設為同樣大小。 800m

-Xmn 是將NewSize與MaxNewSize設為一致。320m

-XX:PerSize 64m

-XX:NewSize 320m 此值設大可調大新對象區,減少Full GC次數

-XX:MaxNewSize 320m

-XX:NewRato NewSize設了可不設。

-XX: SurvivorRatio

-XX:userParNewGC 可用來設置并行收集

-XX:ParallelGCThreads 可用來增加并行度

-XXUseParallelGC 設置后可以使用并行清除收集器

-XX:UseAdaptiveSizePolicy 與上面一個聯合使用效果更好,利用它可以自動優化新域大小以及救助空間比值

6.2.客戶機:通過在JNLP文件中設置參數來調整客戶端JVM

JNLP中參數:initial-heap-size和max-heap-size

這可以在framework的RequestManager中生成JNLP文件時加入上述參數,但是這些值是要求根據客戶機的硬件狀態變化的(如客戶機的內存大小等)。建議這兩個參數值設為客戶機可用內存的60%(有待測試)。為了在動態生成JNLP時以上兩個參數值能夠隨客戶機不同而不同,可靠慮獲得客戶機系統信息并將這些嵌到首頁index.jsp中作為連接請求的參數。

在設置了上述參數后可以通過Visualgc 來觀察垃圾回收的一些參數狀態,再做相應的調整來改善性能。一般的標準是減少fullgc的次數,最好硬件支持使用并行垃圾回收(要求多CPU)。

總結

以上是生活随笔為你收集整理的java 终结此段代码并重新运行_Java垃圾回收的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。