1. 先進行一次thread mp (jstack -m <pid> 或者 kill -3 <pid> , 或者使用jconsole, jvisualvm等) (jstack 命令有一些選項不是每個平台都支持的, jconsole jvisualvm都是有界面的, 如果你要運行一般需要配置agent或者重定向display到某台機器).
2. 然後過了一段時間再做一次, 如果發現同一個thread NID 還是停在同一個地方, 基本上可以懷疑是否掛住了(一般只需要查看你業務相關的stack信息就行了).
3. 還有一種就是你的日誌很詳細, 也可以看到一些的情況(列印到某個地方就卡住了, 呵呵).
『貳』 java 當一個線程結束時(程序還在走),該線程的內存會回收嗎
Java的垃圾回收機制是自動發生的,發生的時間是不確定的,當內存不足是或是cpu空閑的時候,都有可能進行垃圾回收機制,如果想具體了解可以看看Java虛擬機相關內容.
『叄』 Java垃圾回收無效線程嗎
前面是我自己理解的後面是復制的java中垃圾回收以前聽老師講好像是內存滿了他才去做一次整體垃圾回收,在回收垃圾的同時會調用finalize方法.你在構造一個類時可以構造一個類時覆蓋他的finalize方法以便於該類在被垃圾回收時執行一些代碼,比如釋放資源.1.JVM的gc概述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.SunHotSpot1.4.1JVM堆大小的調整SunHotSpot1.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標志來增加永久域搭大小。在WebLogicServer應用程序載入較多類時,經常需要增加永久域的最大值。當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:maxtenuringthreshold可控制上限。為放置所有的復制全部發生以及希望對象從eden擴展到舊域,可以把MaxTenuringThreshold設置成0。設置完成後,實際上就不再使用救助空間了,因此應把SurvivorRatio設成最大值以最大化Eden空間,設置如下:java…-XX:MaxTenuringThreshold=0–XX:SurvivorRatio=50000…4.BEAJRockitJVM的使用BeaWebLogic8.1使用的新的JVM用於Intel平台。在Bea安裝完畢的目錄下可以看到有一個類似於jrockit81sp1_141_03的文件夾。這就是Bea新JVM所在目錄。不同於HotSpot把Java位元組碼編譯成本地碼,它預先編譯成類。JRockit還提供了更細致的功能用以觀察JVM的運行狀態,主要是獨立的GUI控制台(只能適用於使用Jrockit才能使用jrockit81sp1_141_03自帶的console監控一些cpu及memory參數)或者WebLogicServer控制台。BeaJRockitJVM支持4種垃圾收集器:4.1.1.分代復制收集器它與默認的分代收集器工作策略類似。對象在新域中分配,即JRockit文檔中的nursery。這種收集器最適合單cpu機上小型堆操作。4.1.2.單空間並發收集器該收集器使用完整堆,並與背景線程共同工作。盡管這種收集器可以消除中斷,但是收集器需花費較長的時間尋找死對象,而且處理應用程序時收集器經常運行。如果處理器不能應付應用程序產生的垃圾,它會中斷應用程序並關閉收集。分代並發收集器這種收集器在護理域使用排它復制收集器,在舊域中則使用並發收集器。由於它比單空間共同發生收集器中斷頻繁,因此它需要較少的內存,應用程序的運行效率也較高,注意,過小的護理域可以導致大量的臨時對象被擴展到舊域中。這會造成收集器超負荷運作,甚至採用排它性工作方式完成收集。4.1.3.並行收集器該收集器也停止其他進程的工作,但使用多線程以加速收集進程。盡管它比其他的收集器易於引起長時間的中斷,但一般能更好的利用內存,程序效率也較高。默認狀態下,JRockit使用分代並發收集器。要改變收集器,可使用-Xgc:,對應四個收集器分別為gen,singlecon,gencon以及parallel。可使用-Xms和-Xmx設置堆的初始大小和最大值。要設置護理域,則使用-Xns:java–jrockit–Xms512m–Xmx512m–Xgc:gencon–Xns128m…盡管JRockit支持-verbose:gc開關,但它輸出的信息會因收集器的不同而異。JRockit還支持memory、load和codegen的輸出。注意:如果使用JRockitJVM的話還可以使用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:PerSize64m-XX:NewSize320m此值設大可調大新對象區,減少FullGC次數-XX:MaxNewSize320m-XX:NewRatoNewSize設了可不設。-XX:SurvivorRatio-XX:userParNewGC可用來設置並行收集-XX:ParallelGCThreads可用來增加並行度-XXUseParallelGC設置後可以使用並行清除收集器-XX:UseAdaptiveSizePolicy與上面一個聯合使用效果更好,利用它可以自動優化新域大小以及救助空間比值6.2.客戶機:通過在JNLP文件中設置參數來調整客戶端JVMJNLP中參數:initial-heap-size和max-heap-size這可以在framework的RequestManager中生成JNLP文件時加入上述參數,但是這些值是要求根據客戶機的硬體狀態變化的(如客戶機的內存大小等)。建議這兩個參數值設為客戶機可用內存的60%(有待測試)。為了在動態生成JNLP時以上兩個參數值能夠隨客戶機不同而不同,可靠慮獲得客戶機系統信息並將這些嵌到首頁index.jsp中作為連接請求的參數。在設置了上述參數後可以通過Visualgc來觀察垃圾回收的一些參數狀態,再做相應的調整來改善性能。一般的標準是減少fullgc的次數,最好硬體支持使用並行垃圾回收(要求多CPU)。
『肆』 java垃圾回收機制
java垃圾回收就是 系統自動把heap(堆)中沒有引用指向的對象定期刪除
這個是定期自動調用,一般不用去考慮回收的時間點,另外,如果heap中對象比內存多,這時是會報錯的。
JAVA垃圾回收機制另一個特點是,進行垃圾回收的線程是一種低優先順序的線程,在一個Java程序的生命周期中,它只有在內存空閑的時候才有機會運行。
垃圾回收線程遵循以下兩個特性。
1. 自動性。Java技術提供了一個系統級的線程,即垃圾收集器線程,來跟蹤每一塊分配出去的內存空間,當Java 虛擬機處於空閑循環時,垃圾收集器線程會自動檢查每一塊分配出去的內存空間,然後自動回收每一塊可以回收的無用的內存塊。
2. 不可預期性。一個對象成為了垃圾,但是你不能斷言,該對象在這行以後就立刻被清除,甚至有可能當程序結束後,該對象仍然佔用內存。像Windows這樣的軟體常常會出現內存不足的情況,JAVA程序很少出現就是因為可以自動回收內存。然而,因為JAVA也不能保證及時地清除無用的對象,所以JAVA程序也會出現內存不足的情況,只是這種情況很少出現。垃圾收集線程在一個Java程序中的執行是自動的,不能強制執行,即使程序員能明確地判斷出有一塊內存已經無用了,是應該回收的,程序員也不能強制垃圾收集器回收該內存塊。程序員唯一能做的就是通過調用System.gc 方法來"建議"執行垃圾收集器,但其是否可以執行,什麼時候執行卻都是不可知的。
『伍』 2020-10-06:java中垃圾回收器讓工作線程停頓下來是怎麼做的
1、jvm中,在執行垃圾收集演算法時,Java應用程序的其他所有除了垃圾收集收集器線程之外的線程都被掛起。此時,系統只能允許GC線程進行運行,其他線程則會全部暫停,等待GC線程執行完畢後才能再次運行。這些工作都是由虛擬機在後台自動發起和自動完成的,是在用戶不可見的情況下把用戶正常工作的線程全部停下來,這對於很多的應用程序,尤其是那些對於實時性要求很高的程序來說是難以接受的。 但不是說GC必須STW(Stop-The-World,全局暫停),你也可以選擇降低運行速度但是可以並發執行的收集演算法,這取決於你的業務。
『陸』 java中某一個函數或者線程執行完畢後,裡面創建的對象會不會被回收急急急急急急急急急!!!
d會被回收
abc不會 更確切的說是 123456 這個字元串對象不會被回收
java程序里字元串對象一旦被創建就會一直存在就算失去了所有引用也是一樣
不會造成泄漏 用了clear() 就等於把引用全都刪除了 失去了所有引用的對象(除了字元串對象)會被垃圾處理
『柒』 Java線程是否會被垃圾回收
上面的常式運行結果是兩個線程在程序被強制終止之前一直運行。threadisrunning...threadisrunning...threadisrunning...ExecutedSystem.gc(),WeakReferencestillkeepThread[Thread-0,5,main]threadisrunning...threadisrunning...threadisrunning...ExecutedSystem.gc(),WeakReferencestillkeepThread[Thread-0,5,main]threadisrunning...threadisrunning...
運行中的線程是稱之為垃圾回收根對象的一種,不會被垃圾回收。當垃圾回收器判斷一個對象是否可達,總是使用垃圾回收根對象作為參考點。
例如,主線程並沒有被引用,但是不會被垃圾回收。
垃圾回收根對象是可在堆之外被訪問的對象。一個對象可由於下列原因成為GC根對象:SystemClass
由自舉/系統類載入器載入的類。例如,rt.jar中所有諸如java.util.*的類。
JNILocal
原生代碼中的本地變數,例如用戶定義的JNI代碼或JVM內部代碼。
JNIGlobal
原生代碼中的全局變數,例如用戶定義的JNI代碼或JVM內部代碼。
ThreadBlock
當前活躍的線程塊中引用的對象。
Thread
啟動且未停止的線程。
BusyMonitor
其wait()或notify()方法被調用,或被同步synchronized的對象。例如,通過調用synchronized(Object)或者進入其某個synchronized方法。靜態方法對應類,非靜態方法對應對象。
JavaLocal
本地變數。例如,仍在線程的棧中的方法輸入參數或本地創建的對象。
NativeStack
(例如用戶定義的JNI代碼或JVM內部代碼這樣的)原生代碼的入或出參數。通常發生在許多方法有原生部分,方法參數處理的對象成為GC根對象。例如,參數用於文件、網路I/O或反射。
Finalizer
在隊列中等待其finalizer運行的對象。
Unfinalized
擁有finalize方法,但是還沒有被終結且不在finalizer隊列的對象。
Unreachable
從其他根對象不可達的對象,但是被內存分析器標記為根對象。
Unknown
沒有根類型的對象。一些轉儲(mp),例如IBM可移植對轉儲文件,沒有根信息。對於這些轉儲,內存分析器解析程序將沒有被其他根對象引用的對象標記為此類根對象。參考