A. 強制gc怎麼實現
垃圾回收器只能回收那些失去引用的對象比如:
A a1=new A[];
al=null;
這個時候調用System.gc()的話就能把a1之前指向的A的對象給回收了。
簡介:
java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java虛擬機(JVM)的堆中儲存著正在運行的應用程序所建立的所有對象,這些對象通過new、newarray、anewarray和multianewarray等指令建立,但是它們不需要程序代碼來顯式地釋放。
一般來說,堆的是由垃圾回收 來負責的,盡管JVM規范並不要求特殊的垃圾回收技術,甚至根本就不需要垃圾回收,但是由於內存的有限性,JVM在實現的時候都有一個由垃圾回收所管理的堆。
垃圾回收是一種動態存儲管理技術,它自動地釋放不再被程序引用的對象,按照特定的垃圾收集演算法來實現資源自動回收的功能。
B. java 中的gc是怎麼一回事,內部運行是什麼樣的
就是垃圾回收。
在虛擬機中將對象分為新生代,舊生代和永生代,使用不同的演算法進行回收。
C. JVM有哪些垃圾回收演算法
標記-清除,標記-復制,標記-整理
D. 如何設置java gc回收演算法
在java和c#語言中,使用的是託管代碼,不像c++語言那樣由程序員進行內存的手動分配和回收,java語言則由JVM即Java虛擬機 全權負責堆內存的管理,這樣子大大減少了程序員的負擔,同時一定程度上提高了開發效率和系統穩定性,而常用的GC垃圾回收演算法有哪些呢?
Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java虛擬機(JVM)的堆中儲存著正在運行的應用程序所建立的所有對象,這些對象通過new、newarray、anewarray和multianewarray等指令建立,但是它們不需要程序代碼來顯式地釋放。一般來說,堆的是由垃圾回收 來負責的,盡管JVM規范並不要求特殊的垃圾回收技術,甚至根本就不需要垃圾回收,但是由於內存的有限性,JVM在實現的時候都有一個由垃圾回收所管理的堆。垃圾回收是一種動態存儲管理技術,它自動地釋放不再被程序引用的對象,按照特定的垃圾收集演算法來實現資源自動回收的功能。
E. java的gc為什麼要分代
假如哈,現在的計算機能做的1ms掃描完所有live object,10ms完成live set的整理(compaction),大多數java應用都會覺得「這沒毛病了」,那麼,現在Hotspot JVM設計的那幾套GC演算法組合確實就沒意義了。下面,再繼續談一哈GC的哲學。類似分布式系統的CAP theorem,GC演算法設計也是有這個3取2的三角組合的:即延時(latency)、吞吐(throughput)和內存消耗(footprint)。基本的設計原理就是footprint為有限值的條件下,我們再在latency和throughput上挑一個優化,比如Hotspot JVM實現中,CMS演算法主攻latency,Parallel GC 主攻throughput,G1 GC較關注latency同時兼顧一點throughput。來來來,我們開個腦洞:我們能不能放棄或減弱「footprint為有限值」這個條件。嗯~比如,一個應用1小時使用100G memory(暫時不管這100G會產生多少垃圾),伺服器24小時會重啟一次,那麼,每次重啟前java應用需要使用的內存會達到2,400G。也就是說,在這個case中,java能使用的內存如果能大於2,400G,我們根本就是不需要任何GC演算法,not to mention 什麼分代了; 「java的gc為什麼要分代」的哲學又是啥。我認為,是熵增原理 和 80/20法則。
F. 誰能簡單概括下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的基本原理就是找到程序中不再被使用的對象,然後回收掉這些對象佔用的內存。主要的收集器有哪些?引用計數器和跟蹤計數器兩種。引用計數器記錄對象是否被引用,當計數器為零時,說明對象已經不再被使用,可以進行回收。java中的對象有復雜的引用關系,不是很適合引用計數器,所以sunjdk中並沒有實現這種GC方式。跟蹤收集器,全局記錄數據的引用狀態,基於一定的條件觸發。執行的時候,從根集合開始掃描對象的引用關系,主要有復制(ing)、標記-清除(Mark-Sweep)、標記-壓縮(Mark-Compact)那種演算法。
G. java常見gc演算法有哪些
1:標記—清除 Mark-Sweep
過程:標記可回收對象,進行清除
缺點:標記和清除效率低,清除後會產生內存碎片
2:復制演算法
過程:將內存劃分為相等的兩塊,將存活的對象復制到另一塊內存,把已經使用的內存清理掉
缺點:使用的內存變為了原來的一半
進化:將一塊內存按8:1的比例分為一塊Eden區(80%)和兩塊Survivor區(10%)
每次使用Eden和一塊Survivor,回收時,將存活的對象一次性復制到另一塊Survivor上,如果另一塊Survivor空間不足,則使用分配擔保機制存入老年代
3:標記—整理 Mark—Compact
過程:所有存活的對象向一端移動,然後清除掉邊界以外的內存
4:分代收集演算法
過程:將堆分為新生代和老年代,根據區域特點選用不同的收集演算法,如果新生代朝生夕死,則採用復制演算法,老年代採用標記清除,或標記整理
面試的話說出來這四種足夠了
H. 兩種gc的區別
GC有兩種類型:Scavenge GC和Full GC,兩種gc的區別如下:
Scavenge GC一般情況下,當新對象生成,並且在Eden申請空間失敗時,就會觸發Scavenge GC,對Eden區域進行GC,清除非存活對象,並且把尚且存活的對象移動到Survivor區。然後整理Survivor的兩個區。這種方式的GC是對 年輕代的Eden區進行,不會影響到年老代。因為大部分對象都是從Eden區開始的,同時Eden區不會分配的很大,所以Eden區的GC會頻繁進行。因 而,一般在這里需要使用速度快、效率高的演算法,使Eden去能盡快空閑出來。
Full GC對整個堆進行整理,包括Young、Tenured和Perm。Full GC因為需要對整個對進行回收,所以比Scavenge GC要慢,因此應該盡可能減少Full GC的次數。在對JVM調優的過程中,很大一部分工作就是對於FullGC的調節。
I. GC是如何是如何啟動及GC中的演算法等
首先,我們先看看GC處理的內存區域在hotSpot(jdk1.8用的這個虛擬機)中是如何劃分的.
虛擬機將內存劃分為兩大區域,新生代與老年代.
而在新生代中
虛擬機又將區域劃分為Eden和兩塊survivor,新創建的對象將會在佔有較大區域的Eden和一塊survivor,當GC處理垃圾是首先進行標記,會將剩餘的存活對象復制之後放在另外survivor中,然後進行清除,清除之會.
那麼這里就有一個問題,如果存活對象過多 survivor放不下怎麼辦?
這里就會使用擔保:將溢出的對象放入老年代之中.
如果是老年代那,因為老年代的對象的存活能力很強,且無法有空間為老年代進行擔保,所以老年代使用的事 標記-整理
演算法進行垃圾回收的,當GC標記清除了可回收的對象,會將剩餘對象向一端移動.
那麼GC是如何一步步的進行垃圾回收的那?
首先GC要啟動可達性演算法,那麼GC是如何快速的找出所有的GCROOTS節點的那?
1. hotSpot是使用OopMap這樣一組數據結構進行記錄的,類載入完成之後
會記錄對象內什麼偏移量是什麼類型(書上的話),編譯器也會記錄棧和寄存機中的位置.,而這個數據會在特點的位置進行記錄,這些位置就叫做安全點(safepoint).
還有 GC的啟動需要暫時掛起所有的線程,那麼GC是在什麼時間進行垃圾回收的那?
1.當線程運行到safepoint的時候才會進行GC,那麼GC開始之後需要掛起所有線程,這是GC會選擇使用主動式的搶斷,也就是說GC會設置一個和安全點重合的輪詢點,讓所有線程都去訪問這個輪詢點,如果線程訪問結果為真,那麼就代表線程到了輪詢點,便會記性線程中斷了.