您需要了解的所有有关System.gc()的信息
在本文中,我們?cè)噲D回答有關(guān)System.gc()API調(diào)用的最常見問題。 我們希望它會(huì)有所幫助。
什么是System.gc()?
System.gc()是用Java,Android,C#和其他流行語(yǔ)言提供的API。 當(dāng)被調(diào)用時(shí),它將盡最大努力從內(nèi)存中清除累積的未引用對(duì)象(即垃圾)。
誰(shuí)調(diào)用System.gc()?
可以從應(yīng)用程序堆棧的各個(gè)部分調(diào)用System.gc()調(diào)用:
- 您自己的應(yīng)用程序開發(fā)人員可能正在顯式調(diào)用System.gc()方法。
- 有時(shí)System.gc()可以由您的第三方庫(kù),框架甚至有時(shí)由應(yīng)用程序服務(wù)器觸發(fā)。
- 可以通過使用JMX從外部工具(如VisualVM)觸發(fā)
- 如果您的應(yīng)用程序正在使用RMI,則RMI會(huì)定期調(diào)用System.gc()。
調(diào)用System.gc()有什么弊端?
當(dāng)從您的應(yīng)用程序調(diào)用System.gc()或Runtime.getRuntime()。gc()API調(diào)用時(shí),世界各地的Full GC事件將被觸發(fā)。 在世界各地的完整GC期間,整個(gè)JVM將凍結(jié)(即,正在運(yùn)行的所有客戶交易將被暫停)。 通常,這些完整GC需要很長(zhǎng)時(shí)間才能完成。 因此,在不需要運(yùn)行GC的不必要時(shí)間,它有可能導(dǎo)致不良的用戶體驗(yàn)和SLA。
JVM具有復(fù)雜的算法,該算法始終在后臺(tái)運(yùn)行,進(jìn)行所有計(jì)算以及有關(guān)何時(shí)觸發(fā)GC的計(jì)算。 當(dāng)您調(diào)用System.gc()調(diào)用時(shí),所有這些計(jì)算都將被拋掉。 如果JVM僅在一毫秒后觸發(fā)了GC事件,然后又從應(yīng)用程序中再次調(diào)用System.gc(),該怎么辦? 因?yàn)閺哪膽?yīng)用程序中您不知道GC何時(shí)運(yùn)行。
是否有任何良好/有效的理由來調(diào)用System.gc()?
從應(yīng)用程序調(diào)用System.gc()的原因很多,我們還沒有遇到。 但是,這是我們?cè)谝患掖笮秃娇展镜膽?yīng)用程序中看到的有趣的用例。 該應(yīng)用程序使用1 TB的內(nèi)存。 此應(yīng)用程序的完整GC暫停時(shí)間大約需要5分鐘才能完成。 是的,不要感到震驚,這是5分鐘🙂(但我們也看到了23分鐘的GC暫停時(shí)間的情況)。 為了避免由于此暫停時(shí)間而對(duì)客戶造成的影響,該航空公司已實(shí)施了明智的解決方案。 每天晚上,他們一次從負(fù)載均衡器池中取出一個(gè)JVM實(shí)例。 然后,它們通過該JVM上的JMX顯式觸發(fā)System.gc()調(diào)用。 一旦GC事件完成并且從內(nèi)存中清除了垃圾,他們就會(huì)將該JVM放回到負(fù)載平衡器池中。 通過這種巧妙的解決方案,他們將這5分鐘的GC暫停時(shí)間對(duì)客戶的影響降至最低。
如何檢測(cè)是否從您的應(yīng)用程序進(jìn)行了System.gc()調(diào)用?
如您在“誰(shuí)調(diào)用System.gc()?”中所注意到的那樣。 部分,您可以看到System.gc()調(diào)用將從多個(gè)源進(jìn)行,而不僅僅是從您的應(yīng)用程序源代碼進(jìn)行。 因此,僅搜索應(yīng)用程序代碼'System.gc()'字符串不足以判斷您的應(yīng)用程序是否在進(jìn)行System.gc()調(diào)用。 因此,這構(gòu)成了一個(gè)挑戰(zhàn):如何檢測(cè)是否在整個(gè)應(yīng)用程序堆棧中調(diào)用了System.gc()調(diào)用?
這是GC日志很方便的地方。 在應(yīng)用程序中啟用GC日志 。 實(shí)際上,建議始終在所有生產(chǎn)服務(wù)器中始終啟用GC日志,因?yàn)樗兄谀懦收喜?yōu)化應(yīng)用程序性能。 啟用GC日志會(huì)增加微不足道的開銷(如果可以觀察到的話)。 現(xiàn)在,將您的GC日志上傳到垃圾收集日志分析器工具。
上圖摘自GCeasy生成的報(bào)告的“ GC Causes”部分。 您可以看到“ System.gc()”調(diào)用被調(diào)用304次,占GC暫停時(shí)間的52.42%。
如何刪除System.gc()調(diào)用?
您可以通過以下解決方案刪除顯式的System.gc()調(diào)用:
一個(gè)。 搜索和替換
這可能是一種傳統(tǒng)方法:-),但是可以。 在應(yīng)用程序代碼庫(kù)中搜索“ System.gc()”和“ Runtime.getRuntime()。gc()”。 如果看到匹配項(xiàng),則將其刪除。 如果從您的應(yīng)用程序源代碼中調(diào)用“ System.gc()”,則此解決方案將起作用。 如果“ System.gc()”要從您的第三方庫(kù),框架或通過外部源進(jìn)行調(diào)用,則此解決方案將不起作用。 在這種情況下,您可以考慮使用#b中概述的選項(xiàng)。
b。 -XX:+ DisableExplicitGC
啟動(dòng)應(yīng)用程序時(shí),可以通過傳遞JVM參數(shù)'-XX:+ DisableExplicitGC'來強(qiáng)制禁用System.gc()調(diào)用。 此選項(xiàng)將使在應(yīng)用程序堆棧中任何位置調(diào)用的所有“ System.gc()”調(diào)用靜音。
C。 RMI
如果您的應(yīng)用程序使用RMI,則可以控制“ System.gc()”調(diào)用的頻率。 啟動(dòng)應(yīng)用程序時(shí),可以使用以下JVM參數(shù)配置該頻率:
-Dsun.rmi.dgc.server.gcInterval = n
-Dsun.rmi.dgc.client.gcInterval = n
這些屬性的默認(rèn)值在
JDK 1.4.2和5.0是60000毫秒(即60秒)
JDK 6和更高版本是3600000毫秒(即60分鐘)
您可能需要將這些屬性設(shè)置為很高的值,以便可以將影響最小化。
翻譯自: https://www.javacodegeeks.com/2019/09/all-you-need-to-know-about-system-gc.html
總結(jié)
以上是生活随笔為你收集整理的您需要了解的所有有关System.gc()的信息的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 科沃斯设置(科沃斯设置吸力)
- 下一篇: 怎么看路由器被ddos攻击了(怎么看路由