導航:首頁 > 萬維百科 > g1gccms

g1gccms

發布時間:2021-03-18 11:29:20

1、Major GC和Full GC的區別是什麼?觸發條件

你好,關於Major GC和Full GC的區別是什麼呢?
Full GC定義是相對明確的,就是針對整個新生代、老生代、元空間(metaspace,java8以上版本取代perm gen)的全局范圍的GC;
Minor GC和Major GC是俗稱,在Hotspot JVM實現的Serial GC, Parallel GC, cms, G1 GC中大致可以對應到某個Young GC和Old GC演算法組合;
搞清楚了上面這些組合,我們再來看看各類GC演算法的觸發條件。
簡單說,觸發條件就是某GC演算法對應區域滿了,或是預測快滿了。比如,
各種Young GC的觸發原因都是eden區滿了.
條件,Minor GC 執行時暫停的時間將會長很多。

所以 Minor GC 的情況就相當清楚了——每次 Minor GC 會清理年輕代的內存。

Major GC vs Full GC

大家應該注意到,目前,這些術語無論是在 JVM 規范還是在垃圾收集研究論文中都沒有正式的定義。但是我們一看就知道這些在我們已經知道的基礎之上做出的定義是正確的,Minor GC 清理年輕帶內存應該被設計得簡單:

Major GC 是清理永久代。
Full GC 是清理整個堆空間—包括年輕代和永久代。

很不幸,實際上它還有點復雜且令人困惑。首先,許多 Major GC 是由 Minor GC 觸發的,所以很多情況下將這兩種 GC 分離是不太可能的。另一方面,許多現代垃圾收集機制會清理部分永久代空間,所以使用「cleaning」一詞只是部分正確。

這使得我們不用去關心到底是叫 Major GC 還是 Full GC,大家應該關注當前的 GC 是否停止了所有應用程序的線程,還是能夠並發的處理而不用停掉應用程序的線程。
希望對你有幫助

2、cms gc過程中哪幾個階段暫停應用程序

問題解決:中間調整過幾次,先搞了幾台機器做了驗證,後來逐步推廣的。
1、調大heap區,由原來的4g,調整到5g,young區的大小不變,還是2g,這時候old區就由2g變為3g了(這樣保證old區有足夠的空間);
2、設置-XX:UseCMSInitiatingOccupancyOnly,其實這個不關這個問題,只是發現半夜CMS進行的有點頻繁,就禁止掉了悲觀策略;
3、設置CMS區回收的比例,從80%調整到75%,讓old區盡早的進行,有足夠的空間剩餘;

為什麼要有GC(垃圾回收)?

JVM通過GC來回收堆和方法區中的內存,GC的基本原理就是找到程序中不再被使用的對象,然後回收掉這些對象佔用的內存。

3、jvm什麼時候會觸發full gc

除直接調用System.gc外,觸發Full GC執行的情況有如下四種。
1. 舊生代空間不足
舊生代空間只有在新生代對象轉入及創建為大對象、大數組時才會出現不足的現象,當執行Full GC後空間仍然不足,則拋出如下錯誤:
java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的FullGC,調優時應盡量做到讓對象在Minor GC階段被回收、讓對象在新生代多存活一段時間及不要創建過大的對象及數組。
2. Permanet Generation空間滿
PermanetGeneration中存放的為一些class的信息等,當系統中要載入的類、反射的類和調用的方法較多時,Permanet Generation可能會被占滿,在未配置為採用CMS GC的情況下會執行Full GC。如果經過Full GC仍然回收不了,那麼JVM會拋出如下錯誤信息:
java.lang.OutOfMemoryError: PermGen space
為避免Perm Gen占滿造成Full GC現象,可採用的方法為增大Perm Gen空間或轉為使用CMS GC。
3. CMS GC時出現promotion failed和concurrent mode failure
對於採用CMS進行舊生代GC的程序而言,尤其要注意GC日誌中是否有promotion failed和concurrent mode failure兩種狀況,當這兩種狀況出現時可能會觸發Full GC。
promotionfailed是在進行Minor GC時,survivor space放不下、對象只能放入舊生代,而此時舊生代也放不下造成的;concurrent mode failure是在執行CMS GC的過程中同時有對象要放入舊生代,而此時舊生代空間不足造成的。
應對措施為:增大survivorspace、舊生代空間或調低觸發並發GC的比率,但在JDK 5.0+、6.0+的版本中有可能會由於JDK的bug29導致CMS在remark完畢後很久才觸發sweeping動作。對於這種狀況,可通過設置-XX:CMSMaxAbortablePrecleanTime=5(單位為ms)來避免。
4. 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間
這是一個較為復雜的觸發情況,Hotspot為了避免由於新生代對象晉升到舊生代導致舊生代空間不足的現象,在進行Minor GC時,做了一個判斷,如果之前統計所得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間,那麼就直接觸發Full GC。
例如程序第一次觸發MinorGC後,有6MB的對象晉升到舊生代,那麼當下一次Minor GC發生時,首先檢查舊生代的剩餘空間是否大於6MB,如果小於6MB,則執行Full GC。
當新生代採用PSGC時,方式稍有不同,PS GC是在Minor GC後也會檢查,例如上面的例子中第一次Minor GC後,PS GC會檢查此時舊生代的剩餘空間是否大於6MB,如小於,則觸發對舊生代的回收。
除了以上4種狀況外,對於使用RMI來進行RPC或管理的Sun JDK應用而言,默認情況下會一小時執行一次Full GC。可通過在啟動時通過- java-Dsun.rmi.dgc.client.gcInterval=3600000來設置Full GC執行的間隔時間或通過-XX:+ DisableExplicitGC來禁止RMI調用System.gc。

4、Oracle JDK8在JVM上的改進有哪些意義

就垃圾回收機制來說,主要是三點.
1. JEP 173: Retire Some Rarely-Used GC Combinations
只要記住流行的組合就這幾種情況
Serial
ParNew + CMS
ParallelYoung + ParallelOld
G1GC
2. G1 proction ready
有功夫琢磨一下都可以用起來了。有疑惑report到[email protected],或 bug report至 [email protected]
3. JEP 122: Remove the Permanent Generation
省去維護perm gen的overhead,但並不是就一勞永逸了,metaspace要爆還是會爆的!

5、eclipse啟動很慢如何解決

可以參考如下幾個提升eclipse啟動速度的技巧:
技巧一:運行最新版本的JDK和Eclipse
通常,新版本的JDK和Eclipse都會有性能上的優化。請確保你使用的是64位Eclipse並且使用了Oracle的JDK。對於網路開發,需要使用Eclipse for Java EE而不是Eclipse for Java。

技巧二:調整Eclipse的Preferences
General > Startup and Shutdown : 移除所有在啟動時載入的插件。
General > Editors > Text Editors > Spelling : 關閉拼寫檢查。
General > Validation > 勾選「Suspend all validator」。
Window > Customize Perspective > 移除所有用不到或不想用的內容(盡量使用快捷鍵),菜單欄也是如此(你用過幾次菜單欄的列印按鈕?)。
Install/Update > Automatic Updates > 取消勾選「Automatically find new updates and notify me」。
General > Appearance > 取消勾選「Enable Animations」。
使用默認的主題。其他主題可能會降低運行速度。
我自己還關閉了自動提示,這樣在輸入代碼時不會拖累我。替代方案是使用Ctrl+Space在需要的使用手動提示。可以通過下面的配置來完成:(譯者註:Ctrl+Space?中國人不會答應的)。
Java > Editor > Content Assist > 禁用「Enable Auto Activation」。在Advanced中移除所有不需要的內容(在Eclipse 4.2.2中沒找到)。

技巧三:將JDK放在內存檔(RAM Disk)上
內存檔是將計算機內存的作為虛擬磁碟或硬碟使用。用來加速位於其中的軟體的IO性能。內存中創建的RAM盤就像是計算機上的一塊硬碟。由於這些內存當作硬碟使用,所以其他程序就不能使用這些內存空間。我們只是將JDK放到那裡,300MB就足夠了。
警告:不要將任何內容永久性的放到內存檔中,每次重啟時,裡面的內容都會消失並重新創建。
對於Linux用戶:
這個鏈接中有詳細的描述。
對於Mac用戶:
使用diskutil工具創建內存檔
1. 創建一個新的腳本,例如:~/tools/batch/ramdisk.sh
將其中的x、y、z替換為你的JDK版本:
#!/bin/bash
diskutil erasevolume HFS+ 'JDK RAMDISK' `hdiutil attach -nomount ram://614400`
cp -r /Library/Java/JavaVirtualMachines/jdk1.x.y_z.jdk /Volumes/JDKRAMDISK
(注意:diskutil期望的參數是512位元組扇區的整數倍:對於300MB,應該是300 * 1024 ^ 2 / 512 = 614400)
2. 保存腳本,將其改為可執行模式:
chmod 755 ~/tools/batch/ramdisk.sh
運行ramdisk.sh將創建內存檔:
$ ramdisk.sh
Started erase on disk4
Unmounting disk
Erasing
Initialized /dev/rdisk4 as a 300 MB case-insensitive HFS Plus volume
Mounting disk
Finished erase on disk4 JDKRAMDISK
現在用Finder應該能發現一個名為JDKRAMDISK的新設備,其中含有的就是JDK。點擊「彈出」按鈕可以移除RAM Disk並釋放相應的內存。
如果想使用這個技巧,那麼每次啟動Eclipse都需要有這個內存檔,不然會看到「A Java Runtime … must be available in order to run Eclipse」錯誤。可以配置系統,用Automator或一個unchtl守護程序確保每次啟動時會自動執行ramdisk.sh腳本。
對於Windows用戶:
1. 下載並安裝名為imdisk的工具
2. 創建一個新的批處理文件,如:C:/tools/batch/ramdisk.bat
將其中的x、y、z替換為你的JDK版本號:
@echo Placing JDK on Virtual Disk N:/
@echo off
sc config imdisk start= auto
net start imdisk
imdisk -a -t vm -s 300m -m n:
format n: /q /Y
call xcopy C:<path_jdk>jdk1.x.y_z N:jdk1.x.y_z /S /E /Y /Q
label n: JDK RAMDISK
運行ramdisk.bat後,將看到創建了一個名為「JDK RAMDISK」的新磁碟N,其中含有的就是JDK。
3. 確保文件以管理員模式運行。右擊文件,選擇「屬性——兼容性——勾選「以管理員身份運行此程序」。
如果想使用這個技巧,那麼每次啟動Eclipse都需要有這個內存檔,不然會看到「A Java Runtime … must be available in order to run Eclipse」錯誤。可以配置系統,將ramdisk.bat腳本放到啟動文件夾中。
為了讓技巧3能夠工作,需要在eclipse.ini文件中添加-vm設置(詳見下一節)。

技巧四:調整你的eclipse.ini
在Eclipse的優化中,這是最令人困惑的地方。網上有海量的文章介紹不同的配置方案。我只是介紹我自己的配置方案。
找到你的eclipse.ini文件:
Windows/Linux:位於$ECLIPSE_HOME(譯者註:$ECLIPSE_HOME是Eclipse的路徑,這里假設Linux下也是自行安裝,而不是通過源安裝)
MacOS:位於$ECLIPSE_HOME/Eclipse.app/Contents/MacOS
明白接下來的工作的含義……
eclipse.ini中有兩種類型的屬性:與Eclipse應用相關的屬性;與JVM相關的屬性。這些選項具體取決於JDK和Eclipse的版本。下面的是我在網上找到的最新的列表。
要理解這些屬性,首先要了解Oracle JVM的內存布局。一般來說,JVM內存分成幾個內存池,對象根據不同存在時間位於不同的內存池中。
Eden空間(堆)是用於許多剛創建的對象。垃圾收集器每趟一般都是在這里處理」新代的「對象,並移除所有不再使用的對象。
Survivor空間(堆)含有那些在Eden空間中GC兩三趟都沒有銷毀的對象。這些對象依然屬於新生代,但將其移動到更安全的地方,被收集的風險大大降低。垃圾收集器在這里運行的頻率要低很多(GC根據以往的經驗來判斷這里的對象都是經常使用的)。
Tenured空間(堆)含有在Survior空間存活相當一段時間的對象。
永生代(非堆)含有JVM的元數據,如類屬性、方法、枚舉等。由於這些數據可以在多個JVM間共享。所以永生代分只讀和讀寫兩個區域。
代碼緩存(非堆)提供了用於編譯並存儲代碼的內存空間。
如果你對此感興趣,Oracle含有一篇很不錯的關於配置垃圾收集的文章,其中詳細介紹了所有這些空間的用途。
在eclipse.ini中,可以控制每個內存池的大小。下面的配置是針對我的16G內存設定的,但也可用於8G的內存。
使用位於RAM Disk中的JDK(使用在步驟三中的版本號):
-vm /Volumes/JDKRAMDISK/jdk1.x.y_z.jdk/Contents/Home/
-vm N:/jdk1.x.y_z/bin
禁用位元組碼驗證(有風險)
這是跳過了class文件的驗證(class文件的驗證的信息參見這里),意味著JVM不會檢測使用的class文件。如果使用的class文件被修改過,會有安全風險。自己承擔風險(我僅僅是玩的時候用,不會在工作中啟用這個選項)。
打開編譯器性能優化
-XX:+AggressiveOpts
增加永生代空間(分配新對象的地方)(譯者註:在JDK 8中,取消了永生代)
-XX:PermSize=512m
-XX:MaxPermSize=512m
增加最小最大堆的空間(含有新生代和年老代)
-Xms2048m
-Xmx2048m
為新生代增加堆的大小
-Xmn512m
為每個線程設置棧大小
-Xss2m
調整垃圾收集
-XX:+UseParallelOldGC
最後,這里列出其他可能在網上看到的選項。就我個人而言,這些選項都沒有加速效果,所以僅僅是用來參考。讀者可以在網上找到相應的文檔,來了解並使用對應的選項:
-XX:MaxGCPauseMillis=10
-XX:+UseG1GC
-XX:CompileThreshold=5
-XX:MaxGCPauseMillis=10
-XX:MaxHeapFreeRatio=70
-XX:+CMSIncrementalPacing
-XX:+UseFastAccessorMethods
-server
最後,移除所有重復的選項,包括launcher.XXMaxPermSize,因為啟用了XX:MaxPermSize選項後,這個選項就沒用了。

技巧五:關閉殺毒軟體
如果有殺毒軟體,要確保這些軟體不會檢查代碼文件夾。將JDK、Eclipse、你的.m2/jar代碼庫和代碼文件夾添加到殺毒軟體的白名單。

技巧六:不要在Eclipse中運行SVN和GIT
這是個人偏好。有些人喜歡將Eclipse與團隊協同工具結合起來。就我個人而言,這樣速度很慢,我寧願Eclipse專注於開發工作,而不是同時做許多事。我還非常喜歡SVN/GIT命令行。不管怎麼說,我把這些工具從Eclipse中移除,發現響應速度更快了。

技巧七:使用鍵盤
Eclipse的一個有點是其中含有大量快捷鍵。讀者可以自行設置相關快捷鍵。一般我會重新設置調試鍵,這樣就和Visual Studio & Chrome Dev Env的行為相同了。花點時間去學習快捷鍵。用的快捷鍵越多,使用Eclipse的體驗就越快。
這里不會深入介紹快捷鍵,讀者可以很容易的在網上找到相關資料。下面列出一些必備的快捷鍵:
Ctrl+Shift+R : jump to resource
Ctrl+Shift+T : jump to class
Ctrl+. : jump to next error
Ctrl+Shift+G : search for references
Ctrl+Shift+P : select matching bracket
Alt+Arrows : go forward / backwards
Ctrl+Space : autocomplete
Ctrl+Shift+F : format source
Ctrl+Shift+O : organize imports
Ctrl+D : delete line
 

6、如何讓eclipse啟動更快

加快啟動速度 方法
1.在eclipse啟動的時候,它總是會搜索讓其運行的jre,往往就是這個搜索過程讓eclipse啟動變慢了。(沒設置時,等2-3s出現進度條,設置後直接出現進度條)
只要在eclipse.ini中加入-vm的參數就可以了
2.取消所有啟動時要激活的插件(在用時激活也一樣)和其它的相關的在啟動時執行的操作。
3.關閉自動更新
減少jvm內存回收引起的eclipse卡的問題
這個主要是jvm在client模式,進行內存回收時,會停下所有的其它工作,帶回收完畢才去執行其它任務,在這期間eclipse就卡住了。所以適當的增加jvm申請的內存大小來減少其回收的次數甚至不回收,就會是卡的現象有明顯改善。

7、Major GC和Full GC的區別是什麼?觸發條件

Major GC和Full GC的區別是什麼?

Full GC定義是相對明確的,就是針對整個新生代、老生代、元空間(metaspace,java8以上版本取代perm gen)的全局范圍的GC;

2. Minor GC和Major GC是俗稱,在Hotspot JVM實現的Serial GC, Parallel GC, CMS, G1 GC中大致可以對應到某個Young GC和Old GC演算法組合;

搞清楚了上面這些組合,我們再來看看各類GC演算法的觸發條件。

簡單說,觸發條件就是某GC演算法對應區域滿了,或是預測快滿了。比如,

各種Young GC的觸發原因都是eden區滿了.

希望對你有幫助

8、eclipse 的c/c++ indexer 經常將空間耗盡造成Error: Java heap space Java heap space,怎麼解決?

1打開編譯器性能優化 -XX:+AggressiveOpts
2增加永生代空間-XX:PermSize=2048m -XX:MaxPermSize=2048m
3增加最小最大堆的空間-Xms2048m -Xmx2048m
4為新生代增加堆的大小 -Xmn512m
5為每個線程設置棧大小 -Xss2m
6調整垃圾收集 -XX:+UseParallelOldGC
如還不行,繼續優化
-XX:MaxGCPauseMillis=10
-XX:+UseG1GC
-XX:CompileThreshold=5
-XX:MaxGCPauseMillis=10
-XX:MaxHeapFreeRatio=70
-XX:+CMSIncrementalPacing
-XX:+UseFastAccessorMethods
-server
最後,移除所有重復的選項,包括launcher.XXMaxPermSize,因為啟用了XX:MaxPermSize選項後,這個選項就沒用了

9、cms gc為什麼要stop the world

無論你選擇什麼gc,停頓都是不可避免的。CMS在初始標記和重復標記階段會停頓,最新的G1在初始標記階段也會停頓。並發gc只是把一(大)部分工作並發處理了,還是會停頓,只是時間短很多。
另外,也並不一定停頓時間短就是最好的,並發gc會跟用戶線程搶cpu。
因為full gc耗時遠高於minor gc,可能你那個說法忽略了minor gc幾十毫秒的停頓吧

與g1gccms相關的知識