导航:首页 > 源码编译 > 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算法相关的资料

热点内容
不能修改的pdf 浏览:740
同城公众源码 浏览:475
一个服务器2个端口怎么映射 浏览:283
java字符串ascii码 浏览:62
台湾云服务器怎么租服务器 浏览:462
旅游手机网站源码 浏览:317
android关联表 浏览:930
安卓导航无声音怎么维修 浏览:322
app怎么装视频 浏览:424
安卓系统下的软件怎么移到桌面 浏览:81
windows拷贝到linux 浏览:757
mdr软件解压和别人不一样 浏览:889
单片机串行通信有什么好处 浏览:326
游戏开发程序员书籍 浏览:849
pdf中图片修改 浏览:275
汇编编译后 浏览:480
php和java整合 浏览:835
js中执行php代码 浏览:447
国产单片机厂商 浏览:63
苹果手机怎么设置不更新app软件 浏览:289