導航:首頁 > 源碼編譯 > sweep演算法

sweep演算法

發布時間:2022-10-28 16:40:51

① 舉例說明一個典型的垃圾回收演算法

關於java里的垃圾回收演算法,初學者經常產生的疑問是,像這樣的代碼里的無用單元:
class Test{
public Test test = null;
public static void main(String args[]){
Test t1 = new Test();
Test t2 = new Test();
t1.test=t2;
t2.test=t1;
t1=null;
t2=null;
}
}
java能不能自動回收?

java是可以回收的.對此有疑問的人的想法是以為java是採用引用計數法實現垃圾回收的.實際上,java不是用此方法,所以可以回收.
1:引用計數,如下,當單元count=0時回收此單元
Test t1 = new Test();//t1指向單元count=1
Test t2 = new Test();//t2指向單元count=1
t1.test=t2;//t2指向單元count++,count=2
t2.test=t1;//t2指向單元count++,count=2
t1=null;//t1指向單元count--,count=1
t2=null;//t2指向單元count--,count=1
兩單元均不可達,為無用單元,但引用計數count=1,!=0,不能回收.

2:java的演算法(簡化)
基本思想:為了避免懸掛引用,寧可產生無用單元,只在空間用完,需要新單元時才進行垃圾回收.
過程:
1:標記Mark
首先,所有單元標記為off,然後,java所有thread的棧stack內引用的單元標記為on,對所有標記為on的單元引用的其他單元標記為on.
2:掃描Sweep
掃描堆heap,所有標記為off的單元一概回收.

所以,上述程序中無用單元是可以回收的.

② JVM有哪些垃圾回收演算法

標記-清除,標記-復制,標記-整理

③ 現在android上的Dalvik是用哪個垃圾回收演算法

Dalvik虛擬機使用Mark-Sweep演算法來進行垃圾收集。顧名思義,Mark-Sweep演算法就是為Mark和Sweep兩個階段進行垃圾回收。其中,Mark階段從根集(Root Set)開始,遞歸地標記出當前所有被引用的對象,而Sweep階段負責回收那些沒有被引用的對象。

④ 「sweep」的過去時和過去分詞怎麼寫

「sweep」的過去時是swept,過去分詞也是swept。

sweep

英 [swiːp] 美 [swip]

vt. 掃除;猛拉;撣去

vi. 掃,打掃;席捲;掃視;襲擊

n. 打掃,掃除;范圍;全勝

短語

1、sweep off拂去 ; 大量清除 ; 掃去 ; 掃清

2、sweep rate掃描速度 ;[雷達]掃描速率 ;[電子]掃描頻率 ; 掃描率

3、sweep templete造模刮板 ; 制模刮板

4、Temperature Sweep溫度掃描分析 ; 溫度掃描 ; 溫度分析 ; 溫度掃描分析參數設置

5、Sweep Time[電子][計]掃描時間 ; 掃頻速率 ; 掃描 ; 掃描時間英語

6、Sweep speed[電子]掃描速度 ; 掃描速度英語

7、sweep generator[電子]掃描發生器 ; 掃描振盪器 ; 掃頻信號發生器 ; 掃描頻率發生器

8、Sweep Oar單槳 ; 大槳

9、Sweep Algorithm掃描演算法 ; 掃描法 ; 掃描線演算法

(4)sweep演算法擴展閱讀

雙語例句

1、I can't sweep without a broom.

沒有掃帚我無法掃。

2、Sweep the room out well.

把這房間好好打掃一下。

3、Sprinkle some water before you sweep.

先潑點兒水再掃。

4、There are some proposals for removing the rubbish, like creating a series of lasers that would sweep the trash back into our atmosphere, where it would mostly burn up.

有一些關於清除太空垃圾的提議,如創造了一系列的激光將垃圾掃回我們的大氣層,垃圾在大氣層里差不多都能燃燒殆盡。

5、Save Our Secret Ballot amendments prevent adoption of card-check laws by other states—but the NLRB』s lawsuits could sweep those protections aside as well.

《拯救我們的無記名投票》修正案會阻止其他州採用卡片檢查法律——但NLRB的訴訟可能將這些保護也一並掃除。

⑤ JAVA垃圾收集的演算法是怎麼樣的

Java語言規范沒有明確地說明JVM使用哪種垃圾回收演算法,但是任何一種垃圾收集演算法一般要做2件基本的事情:(1)發現無用信息對象;(2)回收被無用對象佔用的內存空間,使該空間可被程序再次使用。 (課課家教育)

大多數垃圾回收演算法使用了根集(root set)這個概念;所謂根集就量正在執行的Java程序可以訪問的引用變數的集合(包括局部變數、參數、類變數),程序可以使用引用變數訪問對象的屬性和調用對象的方法。垃圾收集首選需要確定從根開始哪些是可達的和哪些是不可達的,從根集可達的對象都是活動對象,它們不能作為垃圾被回收,這也包括從根集間接可達的對象。而根集通過任意路徑不可達的對象符合垃圾收集的條件,應該被回收。下面介紹幾個常用的演算法。

1、 引用計數法(Reference Counting Collector)

引用計數法是唯一沒有使用根集的垃圾回收的法,該演算法使用引用計數器來區分存活對象和不再使用的對象。一般來說,堆中的每個對象對應一個引用計數器。當每一次創建一個對象並賦給一個變數時,引用計數器置為1。當對象被賦給任意變數時,引用計數器每次加1當對象出了作用域後(該對象丟棄不再使用),引用計數器減1,一旦引用計數器為0,對象就滿足了垃圾收集的條件。

基於引用計數器的垃圾收集器運行較快,不會長時間中斷程序執行,適宜地必須 實時運行的程序。但引用計數器增加了程序執行的開銷,因為每次對象賦給新的變數,計數器加1,而每次現有對象出了作用域生,計數器減1。

2、tracing演算法(Tracing Collector)

tracing演算法是為了解決引用計數法的問題而提出,它使用了根集的概念。基於tracing演算法的垃圾收集器從根集開始掃描,識別出哪些對象可達,哪些對象不可達,並用某種方式標記可達對象,例如對每個可達對象設置一個或多個位。在掃描識別過程中,基於tracing演算法的垃圾收集也稱為標記和清除(mark-and-sweep)垃圾收集器.

3、compacting演算法(Compacting Collector)

為了解決堆碎片問題,基於tracing的垃圾回收吸收了Compacting演算法的思想,在清除的過程中,演算法將所有的對象移到堆的一端,堆的另一端就變成了一個相鄰的空閑內存區,收集器會對它移動的所有對象的所有引用進行更新,使得這些引用在新的位置能識別原來 的對象。在基於Compacting演算法的收集器的實現中,一般增加句柄和句柄表。

4、ing演算法(Coping Collector)

該演算法的提出是為了克服句柄的開銷和解決堆碎片的垃圾回收。它開始時把堆分成 一個對象 面和多個空閑面, 程序從對象面為對象分配空間,當對象滿了,基於coping演算法的垃圾 收集就從根集中掃描活動對象,並將每個 活動對象復制到空閑面(使得活動對象所佔的內存之間沒有空閑洞),這樣空閑面變成了對象面,原來的對象面變成了空閑面,程序會在新的對象面中分配內存。

一種典型的基於coping演算法的垃圾回收是stop-and-演算法,它將堆分成對象面和空閑區域面,在對象面與空閑區域面的切換過程中,程序暫停執行。

5、generation演算法(Generational Collector)

stop-and-垃圾收集器的一個缺陷是收集器必須復制所有的活動對象,這增加了程序等待時間,這是coping演算法低效的原因。在程序設計中有這樣的規律:多數對象存在的時間比較短,少數的存在時間比較長。因此,generation演算法將堆分成兩個或多個,每個子堆作為對象的一代(generation)。由於多數對象存在的時間比較短,隨著程序丟棄不使用的對象,垃圾收集器將從最年輕的子堆中收集這些對象。在分代式的垃圾收集器運行後,上次運行存活下來的對象移到下一最高代的子堆中,由於老一代的子堆不會經常被回收,因而節省了時間。

6、adaptive演算法(Adaptive Collector)

在特定的情況下,一些垃圾收集演算法會優於其它演算法。基於Adaptive演算法的垃圾收集器就是監控當前堆的使用情況,並將選擇適當演算法的垃圾收集器。

⑥ 各種編程語言的實現都採用了哪些垃圾回收演算法

從各種垃圾收集演算法最基本的運行方式來說,大概可以分成三個類型:

1. 引用計數(reference counting):

基本思路是為每個對象加一個計數器,記錄指向這個對象的引用數量。每次有一個新的引用指向這個對象,計數器加一;反之每次有一個指向這個對象引用被置空或者指向其他對象,計數器減一。當計數器變為 0 的時候,自動刪除這個對象。

引用計數的優點是 1)相對簡單,不需要太多運行時(run-time)的支持,可以在原生不支持 GC 的語言里實現。2)對象會在成為垃圾的瞬間被釋放,不會給正常程序的執行帶來額外中斷。它的死穴是循環引用,對象 A 包含一個引用指向對象 B ,同時對象 B 包含一個引用指向對象 A,計數器就抓瞎了。另外,引用計數對正常程序的執行性能有影響(每次引用賦值都要改計數器),特別是在多線程環境下(改計數器要加鎖同步)。

現在仍然主要採用引用計數的例子有 Apple 的 ARC,C++ 新標准里的 std::shared_ptr。

2. 標記-清掃(mark-sweep)。

基本思路是先按需分配,等到沒有空閑內存的時候從寄存器和程序棧上的引用出發,遍歷以對象為節點、以引用為邊構成的圖,把所有可以訪問到的對象打上標記,然後清掃一遍內存空間,把所有沒標記的對象釋放。

標記-清掃沒有無法處理循環引用的問題,不觸發 GC 時也不影響正常程序的執行性能。但它的問題是當內存耗盡觸發 GC 時,需要中斷正常程序一段時間來清掃內存,在內存大對象多的時候這個中斷可能很長。

採用或者部分採用標記-清掃的例子非常多,不一一列舉了。

3. 節點復制(ing)。

基本思路是把整個內存空間一分為二,不妨記為 A 和 B。所有對象的內存在 A 中分配,當 A 塞滿的時候,同樣從寄存器和程序棧上的引用出發,遍歷以對象為節點、以引用為邊構成的圖,把所有可以訪問到的對象復制到 B 去,然後對調 A 和 B 的角色。

相對於標記-清掃,節點復制的主要缺點是總有一半空間空閑著無法利用,另一個比較隱晦的缺點是它使用內存的方式與現有的內存換頁、Cache 換入換出機制有潛在的沖突。但它有個很大的優點: 所有的對象在內存中永遠都是緊密排列的,所以分配內存的任務變得極為簡單,只要移動一個指針即可。對於內存分配頻繁的環境來說,性能優勢相當大。另外,由於不需要清掃整個內存空間,所以如果內存中存活對象很少而垃圾對象很多的話(有些語言有這個傾向),觸發 GC 造成的中斷會小於標記-清掃。

同樣的,採用或者部分採用節點復制的例子也非常多,不一一列舉了。

⑦ 各種編程語言的實現都採用了哪些垃圾回收演算法

java語言:
. 採用Reference Counting的垃圾回收器
對於採用Reference Counting的垃圾回收器,系統為堆上每一個對象都維護一個計數器,當一個對象被創建並且別引用時,這個計數就被置為1。當有新的變數引用該對象,計數器進行自加運算。當一個引用超出作用范圍或者被賦予新值的時候,計數器進行自減運算。引用計數為0的對象,會被作為垃圾回收。當一個對象被回收,該對象所引用的對象的引用計數都會相應減少,因而,一個對象的回收有時會引起其它對象的回收。
Reference Counting方式的垃圾回收器,好處在於可以在很短的時間內運行,不會長時間的中斷普通的程序運行,因而在RealTime的系統中應用較為普遍。 Reference Counting方式的垃圾回收器,問題在於無法識別循環引用,比如父類對象還有子類引用的情況,即便父類和子類都已經不再能被訪問到(unreachable),引用計數也把它們清除。另外一個問題是引用計數器的加減運算會增加系統的計算開銷。 2. 採用Tracing的垃圾回收器
採用Tracing的垃圾回收器,遍歷由根節點(root nodes)出發的引用關系圖。在遍歷過程中遇到的對象,就被標記為活動。標記既可以是對應對象中的某一個標志,也可以是獨立的點陣圖中的標志。當遍歷完成以後,那些沒有被標記的對象,就被作為垃圾回收了。最基本Tracing演算法是"Mark and Sweep" 垃圾回收器的另外一個責任是清除堆上的碎片(Fragmentation)。對於Mark and Sweep的垃圾回收器通常有兩種實現方法來減少堆上的碎片: 壓縮(Compacting)和拷貝(Copying)

在編程語言Python中,使用也是引用計數演算法。

節點拷貝演算法
節點拷貝演算法是把整個堆分成兩個半區(From,To), GC的過程其實就是把存活對象從一個半區From拷貝到另外一個半區To的過程,而在下一次回收時,兩個半區再互換角色。在移動結束後,再更新對象的指針引用。

⑧ 三種聚類方法:層次、K均值、密度

一、層次聚類

1)距離和相似系數

r語言中使用dist(x, method = "euclidean",diag = FALSE, upper = FALSE, p = 2) 來計算距離。其中x是樣本矩陣或者數據框。method表示計算哪種距離。method的取值有:

euclidean                歐幾里德距離,就是平方再開方。

maximum                切比雪夫距離

manhattan 絕對值距離

canberra Lance 距離

minkowski            明科夫斯基距離,使用時要指定p值

binary                    定性變數距離.

定性變數距離: 記m個項目裡面的 0:0配對數為m0 ,1:1配對數為m1,不能配對數為m2,距離=m1/(m1+m2);

diag 為TRUE的時候給出對角線上的距離。upper為TURE的時候給出上三角矩陣上的值。

r語言中使用scale(x, center = TRUE, scale = TRUE) 對數據矩陣做中心化和標准化變換。

如只中心化 scale(x,scale=F) ,

r語言中使用sweep(x, MARGIN, STATS, FUN="-", ...) 對矩陣進行運算。MARGIN為1,表示行的方向上進行運算,為2表示列的方向上運算。STATS是運算的參數。FUN為運算函數,默認是減法。下面利用sweep對矩陣x進行極差標准化變換

?

1

2

3

>center <-sweep(x, 2, apply(x, 2, mean)) #在列的方向上減去均值。

>R <-apply(x, 2, max) -apply(x,2,min)   #算出極差,即列上的最大值-最小值

>x_star <-sweep(center, 2, R, "/")        #把減去均值後的矩陣在列的方向上除以極差向量

?

1

2

3

>center <-sweep(x, 2, apply(x, 2, min)) #極差正規化變換

>R <-apply(x, 2, max) -apply(x,2,min)

>x_star <-sweep(center, 2, R, "/")

有時候我們不是對樣本進行分類,而是對變數進行分類。這時候,我們不計算距離,而是計算變數間的相似系數。常用的有夾角和相關系數。

r語言計算兩向量的夾角餘弦:

?

1

2

y <-scale(x, center =F, scale =T)/sqrt(nrow(x)-1)

C <-t(y) %*%y

相關系數用cor函數

2)層次聚類法

層次聚類法。先計算樣本之間的距離。每次將距離最近的點合並到同一個類。然後,再計算類與類之間的距離,將距離最近的類合並為一個大類。不停的合並,直到合成了一個類。其中類與類的距離的計算方法有:最短距離法,最長距離法,中間距離法,類平均法等。比如最短距離法,將類與類的距離定義為類與類之間樣本的最段距離。。。

r語言中使用hclust(d, method = "complete", members=NULL) 來進行層次聚類。

其中d為距離矩陣。

method表示類的合並方法,有:

single            最短距離法

complete        最長距離法

median        中間距離法

mcquitty        相似法

average        類平均法

centroid        重心法

ward            離差平方和法

?

1

2

3

4

5

6

7

8

> x <-c(1,2,6,8,11)      #試用一下

> dim(x) <-c(5,1)

> d <-dist(x)

> hc1 <-hclust(d,"single")

> plot(hc1)

> plot(hc1,hang=-1,type="tirangle")             #hang小於0時,樹將從底部畫起。

#type = c("rectangle", "triangle"),默認樹形圖是方形的。另一個是三角形。

#horiz  TRUE 表示豎著放,FALSE表示橫著放。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

> z <-scan()

1: 1.0000.8460.8050.8590.4730.3980.3010.382

9: 0.8461.0000.8810.8260.3760.3260.2770.277

17: 0.8050.8811.0000.8010.3800.3190.2370.345

25: 0.8590.8260.8011.0000.4360.3290.3270.365

33: 0.4730.3760.3800.4361.0000.7620.7300.629

41: 0.3980.3260.3190.3290.7621.0000.5830.577

49: 0.3010.2770.2370.3270.7300.5831.0000.539

57: 0.3820.4150.3450.3650.6290.5770.5391.000

65: 

Read 64items

> names

[1] "shengao""shoubi""shang""xia""tizhong"

[6] "jingwei""xiongwei""xiongkuang"

> r <-matrix(z,nrow=8,dimnames=list(names,names))

> d <-as.dist(1-r)

> hc <-hclust(d)

> plot(hc)

然後可以用rect.hclust(tree, k = NULL, which = NULL, x = NULL, h = NULL,border = 2, cluster = NULL)來確定類的個數。 tree就是求出來的對象。k為分類的個數,h為類間距離的閾值。border是畫出來的顏色,用來分類的。

?

1

2

3

> plot(hc)

> rect.hclust(hc,k=2)

> rect.hclust(hc,h=0.5)

result=cutree(model,k=3) 該函數可以用來提取每個樣本的所屬類別

二、動態聚類k-means

層次聚類,在類形成之後就不再改變。而且數據比較大的時候更占內存。

動態聚類,先抽幾個點,把周圍的點聚集起來。然後算每個類的重心或平均值什麼的,以算出來的結果為分類點,不斷的重復。直到分類的結果收斂為止。r語言中主要使用kmeans(x, centers, iter.max = 10, nstart = 1, algorithm  =c("Hartigan-Wong", "Lloyd","Forgy", "MacQueen"))來進行聚類。centers是初始類的個數或者初始類的中心。iter.max是最大迭代次數。nstart是當centers是數字的時候,隨機集合的個數。algorithm是演算法,默認是第一個。

?

使用knn包進行Kmean聚類分析

將數據集進行備份,將列newiris$Species置為空,將此數據集作為測試數據集

> newiris <- iris

> newiris$Species <- NULL

在數據集newiris上運行Kmean聚類分析, 將聚類結果保存在kc中。在kmean函數中,將需要生成聚類數設置為3

> (kc <- kmeans(newiris, 3)) 

K-means clustering with 3 clusters of sizes 38, 50, 62: K-means演算法產生了3個聚類,大小分別為38,50,62. 

Cluster means: 每個聚類中各個列值生成的最終平均值

  Sepal.Length Sepal.Width Petal.Length Petal.Width

1     5.006000    3.428000     1.462000    0.246000

2     5.901613    2.748387     4.393548    1.433871

3     6.850000    3.073684     5.742105    2.071053

Clustering vector: 每行記錄所屬的聚類(2代表屬於第二個聚類,1代表屬於第一個聚類,3代表屬於第三個聚類)

  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

[37] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

[73] 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 3 3 3 3 2 3

[109] 3 3 3 3 3 2 2 3 3 3 3 2 3 2 3 2 3 3 2 2 3 3 3 3 3 2 3 3 3 3 2 3 3 3 2 3

[145] 3 3 2 3 3 2

Within cluster sum of squares by cluster: 每個聚類內部的距離平方和   

[1] 15.15100 39.82097 23.87947

(between_SS / total_SS =  88.4 %) 組間的距離平方和佔了整體距離平方和的的88.4%,也就是說各個聚類間的距離做到了最大

Available components: 運行kmeans函數返回的對象所包含的各個組成部分

[1] "cluster"      "centers"      "totss"        "withinss"    

[5] "tot.withinss" "betweenss"    "size"  

("cluster"是一個整數向量,用於表示記錄所屬的聚類  

"centers"是一個矩陣,表示每聚類中各個變數的中心點

"totss"表示所生成聚類的總體距離平方和

"withinss"表示各個聚類組內的距離平方和

"tot.withinss"表示聚類組內的距離平方和總量

"betweenss"表示聚類組間的聚類平方和總量

"size"表示每個聚類組中成員的數量)

創建一個連續表,在三個聚類中分別統計各種花出現的次數

> table(iris$Species, kc$cluster)           

              1  2  3

  setosa      0 50  0

  versicolor  2  0 48

  virginica  36  0 14

根據最後的聚類結果畫出散點圖,數據為結果集中的列"Sepal.Length"和"Sepal.Width",顏色為用1,2,3表示的預設顏色

> plot(newiris[c("Sepal.Length", "Sepal.Width")], col = kc$cluster)

在圖上標出每個聚類的中心點

〉points(kc$centers[,c("Sepal.Length", "Sepal.Width")], col = 1:3, pch = 8, cex=2)

三、DBSCAN

動態聚類往往聚出來的類有點圓形或者橢圓形。基於密度掃描的演算法能夠解決這個問題。思路就是定一個距離半徑,定最少有多少個點,然後把可以到達的點都連起來,判定為同類。在r中的實現

dbscan(data, eps, MinPts, scale, method, seeds, showplot, countmode)

其中eps是距離的半徑,minpts是最少多少個點。 scale是否標准化(我猜) ,method 有三個值raw,dist,hybird,分別表示,數據是原始數據避免計算距離矩陣,數據就是距離矩陣,數據是原始數據但計算部分距離矩陣。showplot畫不畫圖,0不畫,1和2都畫。countmode,可以填個向量,用來顯示計算進度。用鳶尾花試一試

?

1

2

3

4

5

6

7

8

9

10

11

> install.packages("fpc", dependencies=T)

> library(fpc)

> newiris <-iris[1:4]

> model <-dbscan(newiris,1.5,5,scale=T,showplot=T,method="raw")# 畫出來明顯不對 把距離調小了一點

> model <-dbscan(newiris,0.5,5,scale=T,showplot=T,method="raw")

> model #還是不太理想……

dbscan Pts=150MinPts=5eps=0.5

        012

border 34518

seed    04053

total  344571

⑨ jvm垃圾回收有哪些演算法

1.堆的分代和區域
(年輕代)Young Generation(eden、s0、s1 space) Minor GC

(老年代)Old Generation (Tenured space) Major GC|| Full GC

(永久代)Permanent Generation (Permanent space)【方法區(method area)】 Major GC

本地化的String從JDK 7開始就被移除了永久代(Permanent Generation )

JDK 8.HotSpot JVM開始使用本地化的內存存放類的元數據,這個空間叫做元空間(Metaspace)

2.判斷對象是否存活(哪些是垃圾對象)
1.引用計數(ReferenceCounting):對象有引用計數屬性,增加一個引用計數加1,減少一個引用計數減1,計數為0時可回收。(無法解決對象相互循環引用的問題)

2.根搜索(GC Roots Tracing):GCRoot對象作為起始點(根)。如果從根到某個對象是可達的,則該對象稱為「可達對象」(存活對象,不可回收對象)。否則就是不可達對象,可以被回收。

下圖中,對象Object6、Object7、Object8雖然互相引用,但他們的GC Roots是不可到達的,所以它們將會被判定為是可回收的對象

3.垃圾收集演算法
1.標記-清除(Mark-Sweep)演算法:

標記清除演算法分為「標記」和「清除」兩個階段:首先標記出需要回收的對象,標記完成之後統一清除對象。

缺點:

1、標記和清除效率不高;

2、產生大量不連續的內存碎片,導致有大量內存剩餘的情況下,由於,沒有連續的空間來存放較大的對象,從而觸發了另一次垃圾收集動作。

2.復制(Copying)演算法:
將可用內存容量劃分為大小相等的兩塊,每次只使用其中的一塊。當這一塊用完之後,就將還存活的對象復制到另外一塊上面,然後在把已使用過的內存空間一次清理掉。這樣使得每次都是對其中的一塊進行內存回收

⑩ 各種編程語言的實現都採用了哪些垃圾回收演算法

java語言: . 採用Reference Counting的垃圾回收器 對於採用Reference Counting的垃圾回收器,系統為堆上每一個對象都維護一個計數器,當一個對象被創建並且別引用時,這個計數就被置為1。當有新的變數引用該對象,計數器進行自加運算。當一個引用超出作用范圍或者被賦予新值的時候,計數器進行自減運算。引用計數為0的對象,會被作為垃圾回收。當一個對象被回收,該對象所引用的對象的引用計數都會相應減少,因而,一個對象的回收有時會引起其它對象的回收。 Reference Counting方式的垃圾回收器,好處在於可以在很短的時間內運行,不會長時間的中斷普通的程序運行,因而在RealTime的系統中應用較為普遍。 Reference Counting方式的垃圾回收器,問題在於無法識別循環引用,比如父類對象還有子類引用的情況,即便父類和子類都已經不再能被訪問到(unreachable),引用計數也把它們清除。另外一個問題是引用計數器的加減運算會增加系統的計算開銷。 2. 採用Tracing的垃圾回收器 採用Tracing的垃圾回收器,遍歷由根節點(root nodes)出發的引用關系圖。在遍歷過程中遇到的對象,就被標記為活動。標記既可以是對應對象中的某一個標志,也可以是獨立的點陣圖中的標志。當遍歷完成以後,那些沒有被標記的對象,就被作為垃圾回收了。最基本Tracing演算法是"Mark and Sweep" 垃圾回收器的另外一個責任是清除堆上的碎片(Fragmentation)。對於Mark and Sweep的垃圾回收器通常有兩種實現方法來減少堆上的碎片: 壓縮(Compacting)和拷貝(Copying) 在編程語言Python中,使用也是引用計數演算法。 節點拷貝演算法 節點拷貝演算法是把整個堆分成兩個半區(From,To), GC的過程其實就是把存活對象從一個半區From拷貝到另外一個半區To的過程,而在下一次回收時,兩個半區再互換角色。在移動結束後,再更新對象的指針引用。

閱讀全文

與sweep演算法相關的資料

熱點內容
安卓系統下的軟體怎麼移到桌面 瀏覽:78
windows拷貝到linux 瀏覽:752
mdr軟體解壓和別人不一樣 瀏覽:886
單片機串列通信有什麼好處 瀏覽:321
游戲開發程序員書籍 瀏覽:844
pdf中圖片修改 瀏覽:271
匯編編譯後 瀏覽:476
php和java整合 瀏覽:832
js中執行php代碼 瀏覽:444
國產單片機廠商 瀏覽:57
蘋果手機怎麼設置不更新app軟體 瀏覽:287
轉行當程序員如何 瀏覽:496
蘋果id怎麼驗證app 瀏覽:866
查看手機命令 瀏覽:956
抖音反編譯地址 瀏覽:228
如何加密軟體oppoa5 瀏覽:235
java從入門到精通明日科技 瀏覽:98
拆解汽車解壓視頻 瀏覽:600
新版百度雲解壓縮 瀏覽:594
android上下拉刷新 瀏覽:883