暂无图片
暂无图片
暂无图片
暂无图片
暂无图片
附录E 关于垃圾收集的一些话.pdf
175
4页
0次
2021-02-22
40墨值下载
附录
E
关于垃圾收集的一些话
“很难相信
Java
居然能和
C++
一样快,甚至还能更快一些。
据我自己的实践,这种说法确实成立。然而,我也发现许多关于速度的怀疑都来
自一些早期的实现方式。由于这些方式并非特别有效,所以没有一个模型可供参
考,不能解释
Java
速度快的原因。
我之所以想到速度,部分原因是由于
C++
模型。
C++
将自己的主要精力放在编译
期间“静态”发生的所有事情上,所以程序的运行期版本非常短小和快速。
C++
也直接建立在
C
模型的基础上(主要为了向后兼容)但有时仅仅由于它在
C
能按特定的方式工作,所以也是
C++
中最方便的一种方法。最重要的一种情况是
C
C++
对内存的管理方式,它是某些人觉
Java
速度肯定慢的重要依据:在
Java
中,所有对象都必须在内存“堆”里创建。
而在
C++
中,对象是在堆栈中创建的。这样可达到更快的速度,因为当我们进入
一个特定的作用域时,堆栈指针会向下移动一个单位,为那个作用域内创建的、
以堆栈为基础的所有对象分配存储空间。而当我们离开作用域的时候(调用完毕
所有局部构建器后),堆栈指针会向上移动一个单位。然而,
C++
里创建“内
存堆”
Heap
对象通常会慢得多,因为它建立在
C
的内存堆基础上。这种内存
堆实际是一个大的内存池,要求必须进行再循环(再生)。在
C++
里调
delete
以后,释放的内存会在堆里留下一个洞,所以再调
new
的时候,存储分配机
制必须进行某种形式的搜索,使对象的存储与堆内任何现成的洞相配,否则就会
很快用光堆的存储空间。之所以内存堆的分配会在
C++
里对性能造成如此重大的
性能影响,对可用内存的搜索正是一个重要的原因。所以创建基于堆栈的对象要
快得多。
同样地,由于
C++
如此多的工作都在编译期间进行,所以必须考虑这方面的因素。
但在
Java
的某些地方,事情的发生却要显得“动态”得多,它会改变模型。
建对象的时候,垃圾收集器的使用对于提高对象创建的速度产生了显著的影响。
从表面上看,这种说法似乎有些奇怪——存储空间的释放会对存储空间的分配造
成影响,但它正是
JVM
采取的重要手段之一,这意味着在
Java
中为堆对象分配
存储空间几乎能达到与
C++
中在堆栈里创建存储空间一样快的速度。
可将
C++
的堆(以及更慢的
Java
堆)想象成一个庭院,每个对象都拥有自己
一块地皮。在以后的某个时间这种“不动产”会被抛弃,而且必须再生。但在
某些
JVM
里,
Java
堆的工作方式却是颇有不同的。它更象一条传送带:每次分
配了一个新对象后,都会朝前移动。这意味着对象存储空间的分配可以达到非常
快的速度。“堆指针”简单地向前移至处女地,所以它与
C++
的堆栈分配方式几
乎是完全相同的(当然,在数据记录上会多花一些开销,但要比搜索存储空间快
多了)
现在,大家可能注意到了堆事实并非一条传送带。如按那种方式对待它,最终就
要求进行大量的页交换(这对性能的发挥会产生巨大干扰),这样终究会用光内
存,出现内存分页错误。所以这儿必须采取一个技巧那就是著名的“垃圾收集
器”。它在收集“垃圾”的同时,也负责压缩堆里的所有对象,将“堆指针”移
至尽可能靠近传送带开头的地方,远离发生(内存)分页错误的地点。垃圾收集
器会重新安排所有东西,使其成为一个高速、无限自由的堆模型,同时游刃有余
地分配存储空间。
为真正掌握它的工作原理,我们首先需要理解不同垃圾收集器
GC
)采取的
作方案。一种简单、但速度较慢的
GC
技术是引用计数。这意味着每个对象都包
含了一个引用计数器。每当一个句柄同一个对象连接起来时,引用计数器就会增
值。每当一个句柄超出自己的作用域,或者设为
null
时,引用计数就会减值。
样一来,只要程序处于运行状态,就需要连续进行引用计数管理——尽管这种管
理本身的开销比较少。垃圾收集器会在整个对象列表中移动巡视,一旦它发现其
中一个引用计数成为
0
就释放它占据的存储空间。但这样做也有一个缺点:
对象相互之间进行循环引用,那么即使引用计数不是
0
仍有可能属于应收掉的
“垃圾”。为了找出这种自引用的组,要求垃圾收集器进行大量额外的工作。引
用计数属于垃圾收集的一种类型,但它看起来并不适合在所有
JVM
方案中采用。
在速度更快的方案里,垃圾收集并不建立在引用计数的基础上。相反,它们基于
这样一个原理:所有非死锁的对象最终都肯定能回溯至一个句柄,该句柄要么存
在于堆栈中,要么存在于静态存储空间。这个回溯链可能经历了几层对象。所以,
如果从堆栈和静态存储区域开始,并经历所有句柄,就能找出所有活动的对象。
对于自己找到的每个句柄,都必须跟踪到它指向的那个对象,然后跟随那个对象
中的所有句柄,“跟踪追击”到它们指向的对象……等等,直到遍历了从堆栈或
静态存储区域中的句柄发起的整个链接网路为止。中途移经的每个对象都必须仍
of 4
40墨值下载
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文档的来源(墨天轮),文档链接,文档作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

关注
最新上传
暂无内容,敬请期待...
下载排行榜
Top250 周榜 月榜