javagc
『壹』 java垃圾回收:GC在什麼時候對什麼做了什麼
1、首先,GC又分為minor GC 和 Full GC(major GC)。Java堆內存分為新生代和老年代,新生代中又分為1個eden區和兩個Survior區域。
2、一般情況下,新創建的對象都會被分配到eden區,這些對象經過一個minor gc後仍然存活將會被移動到Survior區域中,對象在Survior中沒熬過一個Minor GC,年齡就會增加一歲,當他的年齡到達一定程度時,就會被移動到老年代中。
3、當eden區滿時,還存活的對象將被復制到survior區,當一個survior區滿時,此區域的存活對象將被復制到另外一個survior區,當另外一個也滿了的時候,從前一個Survior區復制過來的並且此時還存活的對象,將可能被復制到老年代。因為年輕代中的對象基本都是朝生夕死(80%以上),所以年輕代的垃圾回收演算法使用的是復制演算法,復制演算法的基本思想是將內存分為兩塊,每次只有其中一塊,當這一塊內存使用完,就將還活著的對象復制到另一塊上面。復制演算法不會產生內存碎片。
4、在GC開始的時候,對象只會存在於eden區,和名為「From」的Survior區,Survior區「to」是空的。緊接著GCeden區中所有存活的對象都會被復制到「To」,而在from區中,仍存活的對象會根據他們的年齡值來決定去向,年齡到達一定只的對象會被復制到老年代,沒有到達的對象會被復制到to survior中,經過這次gc後,eden區和fromsurvior區已經被清空。這個時候,from和to會交換他們的角色,也就是新的to就是上次GC前的fromMinor GC:從年輕代回收內存。
5、當jvm無法為一個新的對象分配空間時會觸發Minor GC,比如當Eden區滿了。當內存池被填滿的時候,其中的內容全部會被復制,指針會從0開始跟蹤空閑內存。Eden和Survior區不存在內存碎片寫指針總是停留在所使用內存池的頂部。執行minor操作時不會影響到永久代,從永久帶到年輕代的引用被當成GC roots,從年輕代到永久代的引用在標記階段被直接忽略掉(永久代用來存放java的類信息)。如果eden區域中大部分對象被認為是垃圾,永遠也不會復制到Survior區域或者老年代空間。如果正好相反,eden區域大部分新生對象不符合GC條件,Minor GC執行時暫停的線程時間將會長很多。Minor may call "stop the world"。
『貳』 Java中 gc的作用是什麼
System.gc()用來強制立即回收垃圾,即釋放內存。
java對內存的釋放採取的垃圾自動回收機制,在編程的時候不用考慮變數不用時釋放內存,java虛擬機可以自動判斷出並收集到垃圾,但一般不會立即釋放它們的內存空間,當然也可以在程序中使用System.gc()來強制垃圾回收,但是要注意的是,系統並不保證會立即進行釋放內存
『叄』 Java命令行執行gc的命令是什麼
System.gc()
不過java虛擬機的gc過程並不是在調用System.gc()之後立即執行的,而是通知虛擬機這部分內存可以回收了,gc的時機是由虛擬機決定,不同的虛擬機gc線程的優先順序不同,一般都比較低
『肆』 java的gc問題:
我也有類似的問題,PS,你是怎麼檢測gc被執行的?
據我觀察JAVA程序,一般在命令行模式下運行JAVA任務,JDK可以承受的內存上限大概是機器物理內存的1/4。
比如我的伺服器是16G的內存,那麼JAVA程序可以佔用的最大內存是4G左右,超出就報溢出。
所以在一般程序運行中,JAVA內存逐漸從
100MB 200MB, 300...1G...2G...... 膨脹到4G,在這個過程中,我的循環都設置了System.gc(),偶爾有佔用內存減少的時候,但是基本下降都很有限,然後過一會兒又繼續上升。直到上升到4G的時候,如果此時系統沒有明確的數據持續寫進內存,只是大量進行新建變數,賦值,然後生命周期結束待回收的過程,系統會大量進行GC的操作,保證JAVA內存不超過4G,但我似乎感覺一旦在內存在4G上下游動的時候,JAVA程序的性能就開始走低。
所以我的理解是,GC直到不得不執行的時候才會被執行,而且效果並不好。。。。
PS,如果是8G內存的伺服器,GC頻繁執行是在JAVA佔用內存到達2G的時候。
同不知道如何進行高效的內存回收。本來沒有任何寫入內存操作的程序,但是程序處理問題一大了,佔有內存就很多。
『伍』 如何查看 java gc 類型
Java中的GC有哪幾種類型?
參數
描述
UseSerialGC
虛擬機運行在Client模式的默認值,打開此開關參數後,
使用Serial+Serial Old收集器組合進行垃圾收集。
UseParNewGC
打開此開關參數後,使用ParNew+Serial Old收集器組合進行垃圾收集。
UseConcMarkSweepGC
打開此開關參數後,使用ParNew+CMS+Serial Old收集器組合進行垃圾收集。Serial Old作為CMS收集器出現Concurrent Mode Failure的備用垃圾收集器。
UseParallelGC
虛擬機運行在Server模式的默認值,打開此開關參數後,使用Parallel Scavenge+Serial Old收集器組合進行垃圾收集。
UseParallelOldGC
打開此開關參數後,使用Parallel Scavenge+Parallel Old收集器組合進行垃圾收集。
在Java程序啟動完成後,通過jps觀察進程來查詢到當前運行的java進程,使用
jinfo –flag UseSerialGC 進程
的方式可以定位其使用的gc策略,因為這些參數都是boolean型的常量,如果使用該種gc策略會出現+號,否則-號。
使用-XX:+上述GC策略可以開啟對應的GC策略。
GC日誌查看
可以通過在java命令種加入參數來指定對應的gc類型,列印gc日誌信息並輸出至文件等策略。
GC的日誌是以替換的方式(>)寫入的,而不是追加(>>),如果下次寫入到同一個文件中的話,以前的GC內容會被清空。
對應的參數列表
-XX:+PrintGC 輸出GC日誌
-XX:+PrintGCDetails 輸出GC的詳細日誌
-XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準時間的形式)
-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行GC的前後列印出堆的信息
-Xloggc:../logs/gc.log 日誌文件的輸出路徑
這里使用如下的參數來進行日誌的列印:
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs
對於新生代回收的一行日誌,其基本內容如下:
2014-07-18T16:02:17.606+0800: 611.633: [GC 611.633: [DefNew: 843458K->2K(948864K), 0.0059180 secs] 2186589K->1343132K(3057292K), 0.0059490 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
其含義大概如下:
2014-07-18T16:02:17.606+0800(當前時間戳): 611.633(時間戳): [GC(表示Young GC) 611.633: [DefNew(單線程Serial年輕代GC): 843458K(年輕代垃圾回收前的大小)->2K(年輕代回收後的大小)(948864K(年輕代總大小)), 0.0059180 secs(本次回收的時間)] 2186589K(整個堆回收前的大小)->1343132K(整個堆回收後的大小)(3057292K(堆總大小)), 0.0059490 secs(回收時間)] [Times: user=0.00(用戶耗時) sys=0.00(系統耗時), real=0.00 secs(實際耗時)]
老年代回收的日誌如下:
2014-07-18T16:19:16.794+0800: 1630.821: [GC 1630.821: [DefNew: 1005567K->111679K(1005568K), 0.9152360 secs]1631.736: [Tenured:
2573912K->1340650K(2574068K), 1.8511050 secs] 3122548K->1340650K(3579636K), [Perm : 17882K->17882K(21248K)], 2.7854350 secs] [Times: user=2.57 sys=0.22, real=2.79 secs]
gc日誌中的最後貌似是系統運行完成前的快照:
Heap
def new generation total 1005568K, used 111158K [0x00000006fae00000, 0x000000073f110000, 0x0000000750350000)
eden space 893888K, 12% used [0x00000006fae00000, 0x0000000701710e90, 0x00000007316f0000)
from space 111680K, 3% used [0x0000000738400000, 0x000000073877c9b0, 0x000000073f110000)
to space 111680K, 0% used [0x00000007316f0000, 0x00000007316f0000, 0x0000000738400000)
tenured generation total 2234420K, used 1347671K [0x0000000750350000, 0x00000007d895d000, 0x00000007fae00000)
the space 2234420K, 60% used [0x0000000750350000, 0x00000007a2765cb8, 0x00000007a2765e00, 0x00000007d895d000)
compacting perm gen total 21248K, used 17994K [0x00000007fae00000, 0x00000007fc2c0000, 0x0000000800000000)
the space 21248K, 84% used [0x00000007fae00000, 0x00000007fbf92a50, 0x00000007fbf92c00, 0x00000007fc2c0000)
No shared spaces configured.
GC日誌的離線分析
可以使用一些離線的工具來對GC日誌進行分析,比如sun的gchisto( https://java.net/projects/gchisto),gcviewer( https://github.com/chewiebug/GCViewer ),這些都是開源的工具,用戶可以直接通過版本控制工具下載其源碼,進行離線分析。
下面就已gcviewer為例,簡要分析一下gc日誌的離線分析,gcviewer源代碼工程是maven結構的,可以直接用maven進行package,這里編譯的是1.34版本,本版本的快照已經上傳至附件中。
需要說明的是,gcviewer支持多種參數生成的gc日誌,直接通過java –jar的方式運行,載入生成的gc日誌即可:
『陸』 java gc 是在什麼時候,對什麼東西,做了什麼事情
GC是垃圾回收的意思(gabage collection),內存處理器是編程人員容易出現問題的地方,忘記或者錯誤的內存回收導致程序或者系統的不穩定甚至崩潰,java的GC功能可以自動監測對象是否超過作用域從而達到自動回收內存的目的,java語言沒有提供釋放已分配內存的俄顯示操作方法。
『柒』 Java中gc的作用是什麼
System.gc()用來強制立即回收垃圾,即釋放內存。
java對內存的釋放採取的垃圾自動回收機制,在編程的時候不用考慮變數不用時釋放內存,java虛擬機可以自動判斷出並收集到垃圾,但一般不會立即釋放它們的內存空間,當然也可以在程序中使用System.gc()來強制垃圾回收,但是要注意的是,系統並不保證會立即進行釋放內存。
『捌』 java中GC指的是什麼
gc是指垃圾回收機制,當一個對象不能再被後續程序所引用到時,這個對象所佔用的內存空間就沒有存在的意義了,java虛擬機會不定時的去檢測內存中這樣的對象,然後回收這塊內存空間。
『玖』 java方法區有沒有gc
java方法區是存在GC的
回收方法區
方法區即為永久代,主要回收兩部分內容:廢棄常量和無用類。
滿足以下3個條件的類稱之為無用類
該類所所有的對象實例已經被回收,也就是java堆中不存在該類的任何實例
載入該類的ClassLoader已經被回收
該類對應的java.lang.Class對象沒有在任何地方被引用,無法在任何地方通過反射訪問該類的方法。
在大量使用反射、動態代理、CGLib等ByteCode框架、動態生成JSP以及OSGI這類頻繁自定義ClassLoader的場景都需要虛擬機具備類卸載的功能,以保證永久帶不會溢出。