- 浏览: 222752 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
dysking:
SWT 和 JFace -
wangyuhfut:
东西不少啊。学习中。。。
一个比较好、中文说明的emacs配置文件 1 -
pacocai:
呵呵!学习,学习~~~不过要说编辑器的话个人更喜欢用VIM,比 ...
一个比较好、中文说明的emacs配置文件 1 -
zhf1zhf2:
这两百多个记起来也不容易啊
英国人是这样背的! -
regex:
试了两次,都是乱码,版本是23.1.1,看来不适合
汉化 Emacs 菜单
无版本差异
D 是一种全面采用垃圾回收(Garbage Collection)的语言。这意味着它从来不用释放内存。只需要按需分配,然后由垃圾回收程序周期性的将所有未使用的内存返回给可用内存池。
C 和 C++ 程序员习惯于显式的管理内存分配和释放,很可能会怀疑垃圾回收的好处和功
效。对一开始就采用垃圾回收设计的新项目和用垃圾回收改良的现有项目的经验表明:
• 采用垃圾回收的程序更快。这有些违反直觉,但是其原理有:
• 引用计数是解决显式内存分配问题的常用解决方案。实现赋值时递增和递减操
作的代码通常是程序缓慢的原因之一。将其隐藏在智能指针类之后并不能提高
速度。 (无论如何,引用计数也不是全面的解决方案,因为循环引用从不会
被删除。)
• 析构函数用来释放对象获得的资源。对于大多数类来说,这个资源就是内存。
采用垃圾回收,大多数析构函数都可以完全抛弃。
• 当对象在堆栈上分配时,那些负责释放内存的析构函数就变得十分重要。对于
这些函数来说,必须确立一种机制以使异常发生时,每一个函数帧中的析构函
数都会被调用以释放对象持有的内存。如果析构函数变得不相关,就没有设置
特殊的堆栈帧用于处理异常,这样运行也会更快。
• 内存管理代码总量会变少。程序越大,它在cache中的部分的越少;它的调页
越多,它运行的越慢。
• 垃圾回收只会在内存变得紧张时才会运行。当内存尚且宽裕时,程序将全速运
行,不会在释放内存上花费任何时间。
• 相对于过去的缓慢的垃圾回收程序,现代的垃圾回收程序要先进得多。分代,
复制回收程序在很大程度上克服了早期的标记&清除算法的低效。
• 现代垃圾回收程序进行堆紧缩。堆紧缩将减少程序引用的页的数量,这意味着
内存访问命中率将更高,交换将更少。
• 采用垃圾回收的程序不会因为内存泄漏的累积而崩溃。
• 垃圾回收程序回收不被使用的内存,因此不会有“内存泄露”问题;内存泄露会使长
期运行的应用程序逐渐耗尽内存直至使系统崩溃。采用 GC 的程序拥有更长期的稳定
性。
• 采用垃圾回收的程序 有更少的难以发现的指针错漏。 这是因为没有指向已经释放的
内存的悬挂指针。因为没有显式的内存管理代码,也就不可能有相应的错漏。
• 采用垃圾回收的程序的开发和调试更快,因为不用开发、调试、测试或维护显式的释
放代码。
• 采用垃圾回收的程序会明显更小,因为没用用于管理内存释放的代码,也不需要处理
内存释放异常的代码。
垃圾回收并非什么仙丹妙药。它有着以下不足:
• 内存回收何时运行是不可预测的,所以程序可能意外暂停。
• 运行内存回收的时间是没有上界的。尽管在实践中它的运行通常很快,但无法保证这
一点。
• 除了回收程序以外的所有线程在回收进行时都会停止运行。
• 垃圾回收程序也许会留下一些本该回收的内存。在实践中,这不是什么大问题,因为
显式内存回收程序通常会泄露一些内存,这致使它们最终耗尽所有内存,另一个理由
就是显式内存回收程序通常会把内存放回自己的内部内存池中而不是把内存交还给操
作系统。
• 垃圾回收应该被实现为一个基本的操作系统内核服务。但是因为现实并非如此,就造
成了采用垃圾回收的程序被迫带着它们的垃圾回收实现到处跑。尽管这个实现可以被
做成一个共享 DLL ,它也还是程序的一部分。
这些限制可以通过采用 内存管理 中介绍的技术来缓解。
22.1 垃圾回收如何工作
GC 的工作方式:
1. 寻找所有在 GC 所分配的内存里的指针“根”。
2. 递归扫描所有分配的被“根”所指向的内存,查找更多在GC 分配内存内的指针
3. 释放所有没有激活指针指向的 GC 分配的内存。
4. 可能的话就通过复制分配的对象(叫做复制回收器)压缩余下被占用的内存。
22.2 外部代码同垃圾回收对象的协作
垃圾回收程序寻找根的地方有:
1. 它的静态数据段
2. 每个线程的堆栈和寄存器
3. 所有由 std.gc.addRoot() 或 std.gc.addRange() 添加的根
如果对象唯一的根不在它们中,回收程序将会释放它占有的内存。
要避免这种行为,则需要:
• 为对象维护一个根,该根要位于回收程序扫描的区域之内。
• 添加一个根到使用 std.gc.addRoot() 或 std.gc.addRange() 对象里。
• 使用外部代码的存储分配程序重新分配一个对象或者使用 C 运行时库的 malloc/free
。
22.3 指针和垃圾回收程序
D 中的指针可以被粗略地分为两类:指向垃圾回收内存的指针和其他的指针。后者包括由调
用 C 的 malloc() 所创建的指针,从 C 库中获得的指针,指向静态数据的指针,指向堆栈上
对象的指针,等等。对于这些指针,所有 C 中的合法指针的操作都可以应用其上。
但是,对于垃圾回收指针和引用,对指针的操作就有一些限制了。这些限制是不会造成太大
的缺陷,但却会使垃圾回收程序的设计灵活许多。
未定义行为(Undefined behavior):
• 将指针同其他的值进行异或,如同在 C 中在链表中用异或保存指针那种小技巧。
• 不要使用异或技巧交换两个指针的值。
• 使用类型转换和其他的小技巧将指针存储在非指针变量内。
void* p;
...
int x = cast(int)p; // 错误:未定义行为
垃圾回收器在构建根集(root)时不会扫描非指针类型。
• 利用特定的指针对齐的特点在低位或者高位存储 flag :
p = cast(void*)(cast(int)p | 1); // 错误:未定义行为
• 将可能指向垃圾回收堆的值转换为指针:
p = cast(void*)12345678; // error:未定义行为
复制垃圾回收器可能会更改这个值。
• 不要将不同于 null 的“魔数”存入指针。
• 不要将指针值写入到磁盘然后再从磁盘读入到内存。
• 不要使用指针值来计算 hash(哈希)函数。采用复制技术的垃圾回收程序可能会任
意地在内存中移动对象,这会使 hash 值失效。
• 不要依赖指针的顺序:
if (p1 < p2) // 错误:未定义行为
...
因此,再一次提醒,垃圾回收程序可能会在内存中移动对象。
• 不要给指针加上或者减去一个偏移量,不然结果有可能会导致指针指向垃圾回收程序
原来为对象分配的范围之外。
char* p = new char[10];
char* q = p + 6; // 正确
q = p + 11; // 错误:未定义行为
q = p - 1; // 错误:未定义行为
• 如果这些指针可能指向 GC 堆的话,请不要位移它们,如:
align (1) struct Foo
{ byte b;
char* p; // 位移(misaligned)指针
}
如果底层硬件支持位移指针,而且该指针从未用来指向该 GC 堆,则也可以使用它
们。
• 不要使用“一个字节一个字节的”内存复制方式来复制指针值。这样可能会导致中间
条件,到时就没有合法的指针了;而且如果 GC 在此种条件下暂停线程的话,那么它
就会搞乱内存。大部分的 memcpy() 实现是可以工作的,因为它的内部实现完成的
是以排列块大于或等于一个指针大小的方式进行的复制,不过由于 C 标准并不担保
此种实现,因此在使用 memcpy() 时应特别小心。
可靠且可以完成的事情:
• 使用联合共享指针的存储空间:
union U { void* ptr; int value }
• 如果存在指向垃圾回收对象对象内部的指针,就不必维护指向对象开始处的指针。
char[] p = new char[10];
char[] q = p[3..6];
// q 完全可以用来指向整个对象,不需要同时
// 保留 p 。
程序员可以不用指针完成大部分任务。D 提供的各种特征使得人们在决大多数情况下都不需
要显式地使用指针,这些特征包括:引用对象、动态数组和垃圾回收。提供指针的目的是成
功地同 C API 衔接并完成一些低级的工作。
22.4 与垃圾回收程序协作
垃圾回收程序并不能解决所有的内存释放问题。例如,如果保留了一个指向一大块数据的指
针,那么就算它再也用不到了,垃圾回收程序也无法回收这块空间。为了解决这个问题,一
个不错的实际操作就是:在某个对象不再使用时将指向它的引用或指针设置为 null。
这个建议只适用于静态引用或者嵌入到其他对象内的引用。它对于那些存储在堆栈上的引用
没什么意义,因为回收程序并不扫描栈顶之上的部分,并且新的堆栈帧总会被初始化。
22.5 参考
• Wikipedia
• GC 问与答
• 统一处理器——垃圾回收器技术
• 垃圾回收:自动的动态内存管理算法
D 是一种全面采用垃圾回收(Garbage Collection)的语言。这意味着它从来不用释放内存。只需要按需分配,然后由垃圾回收程序周期性的将所有未使用的内存返回给可用内存池。
C 和 C++ 程序员习惯于显式的管理内存分配和释放,很可能会怀疑垃圾回收的好处和功
效。对一开始就采用垃圾回收设计的新项目和用垃圾回收改良的现有项目的经验表明:
• 采用垃圾回收的程序更快。这有些违反直觉,但是其原理有:
• 引用计数是解决显式内存分配问题的常用解决方案。实现赋值时递增和递减操
作的代码通常是程序缓慢的原因之一。将其隐藏在智能指针类之后并不能提高
速度。 (无论如何,引用计数也不是全面的解决方案,因为循环引用从不会
被删除。)
• 析构函数用来释放对象获得的资源。对于大多数类来说,这个资源就是内存。
采用垃圾回收,大多数析构函数都可以完全抛弃。
• 当对象在堆栈上分配时,那些负责释放内存的析构函数就变得十分重要。对于
这些函数来说,必须确立一种机制以使异常发生时,每一个函数帧中的析构函
数都会被调用以释放对象持有的内存。如果析构函数变得不相关,就没有设置
特殊的堆栈帧用于处理异常,这样运行也会更快。
• 内存管理代码总量会变少。程序越大,它在cache中的部分的越少;它的调页
越多,它运行的越慢。
• 垃圾回收只会在内存变得紧张时才会运行。当内存尚且宽裕时,程序将全速运
行,不会在释放内存上花费任何时间。
• 相对于过去的缓慢的垃圾回收程序,现代的垃圾回收程序要先进得多。分代,
复制回收程序在很大程度上克服了早期的标记&清除算法的低效。
• 现代垃圾回收程序进行堆紧缩。堆紧缩将减少程序引用的页的数量,这意味着
内存访问命中率将更高,交换将更少。
• 采用垃圾回收的程序不会因为内存泄漏的累积而崩溃。
• 垃圾回收程序回收不被使用的内存,因此不会有“内存泄露”问题;内存泄露会使长
期运行的应用程序逐渐耗尽内存直至使系统崩溃。采用 GC 的程序拥有更长期的稳定
性。
• 采用垃圾回收的程序 有更少的难以发现的指针错漏。 这是因为没有指向已经释放的
内存的悬挂指针。因为没有显式的内存管理代码,也就不可能有相应的错漏。
• 采用垃圾回收的程序的开发和调试更快,因为不用开发、调试、测试或维护显式的释
放代码。
• 采用垃圾回收的程序会明显更小,因为没用用于管理内存释放的代码,也不需要处理
内存释放异常的代码。
垃圾回收并非什么仙丹妙药。它有着以下不足:
• 内存回收何时运行是不可预测的,所以程序可能意外暂停。
• 运行内存回收的时间是没有上界的。尽管在实践中它的运行通常很快,但无法保证这
一点。
• 除了回收程序以外的所有线程在回收进行时都会停止运行。
• 垃圾回收程序也许会留下一些本该回收的内存。在实践中,这不是什么大问题,因为
显式内存回收程序通常会泄露一些内存,这致使它们最终耗尽所有内存,另一个理由
就是显式内存回收程序通常会把内存放回自己的内部内存池中而不是把内存交还给操
作系统。
• 垃圾回收应该被实现为一个基本的操作系统内核服务。但是因为现实并非如此,就造
成了采用垃圾回收的程序被迫带着它们的垃圾回收实现到处跑。尽管这个实现可以被
做成一个共享 DLL ,它也还是程序的一部分。
这些限制可以通过采用 内存管理 中介绍的技术来缓解。
22.1 垃圾回收如何工作
GC 的工作方式:
1. 寻找所有在 GC 所分配的内存里的指针“根”。
2. 递归扫描所有分配的被“根”所指向的内存,查找更多在GC 分配内存内的指针
3. 释放所有没有激活指针指向的 GC 分配的内存。
4. 可能的话就通过复制分配的对象(叫做复制回收器)压缩余下被占用的内存。
22.2 外部代码同垃圾回收对象的协作
垃圾回收程序寻找根的地方有:
1. 它的静态数据段
2. 每个线程的堆栈和寄存器
3. 所有由 std.gc.addRoot() 或 std.gc.addRange() 添加的根
如果对象唯一的根不在它们中,回收程序将会释放它占有的内存。
要避免这种行为,则需要:
• 为对象维护一个根,该根要位于回收程序扫描的区域之内。
• 添加一个根到使用 std.gc.addRoot() 或 std.gc.addRange() 对象里。
• 使用外部代码的存储分配程序重新分配一个对象或者使用 C 运行时库的 malloc/free
。
22.3 指针和垃圾回收程序
D 中的指针可以被粗略地分为两类:指向垃圾回收内存的指针和其他的指针。后者包括由调
用 C 的 malloc() 所创建的指针,从 C 库中获得的指针,指向静态数据的指针,指向堆栈上
对象的指针,等等。对于这些指针,所有 C 中的合法指针的操作都可以应用其上。
但是,对于垃圾回收指针和引用,对指针的操作就有一些限制了。这些限制是不会造成太大
的缺陷,但却会使垃圾回收程序的设计灵活许多。
未定义行为(Undefined behavior):
• 将指针同其他的值进行异或,如同在 C 中在链表中用异或保存指针那种小技巧。
• 不要使用异或技巧交换两个指针的值。
• 使用类型转换和其他的小技巧将指针存储在非指针变量内。
void* p;
...
int x = cast(int)p; // 错误:未定义行为
垃圾回收器在构建根集(root)时不会扫描非指针类型。
• 利用特定的指针对齐的特点在低位或者高位存储 flag :
p = cast(void*)(cast(int)p | 1); // 错误:未定义行为
• 将可能指向垃圾回收堆的值转换为指针:
p = cast(void*)12345678; // error:未定义行为
复制垃圾回收器可能会更改这个值。
• 不要将不同于 null 的“魔数”存入指针。
• 不要将指针值写入到磁盘然后再从磁盘读入到内存。
• 不要使用指针值来计算 hash(哈希)函数。采用复制技术的垃圾回收程序可能会任
意地在内存中移动对象,这会使 hash 值失效。
• 不要依赖指针的顺序:
if (p1 < p2) // 错误:未定义行为
...
因此,再一次提醒,垃圾回收程序可能会在内存中移动对象。
• 不要给指针加上或者减去一个偏移量,不然结果有可能会导致指针指向垃圾回收程序
原来为对象分配的范围之外。
char* p = new char[10];
char* q = p + 6; // 正确
q = p + 11; // 错误:未定义行为
q = p - 1; // 错误:未定义行为
• 如果这些指针可能指向 GC 堆的话,请不要位移它们,如:
align (1) struct Foo
{ byte b;
char* p; // 位移(misaligned)指针
}
如果底层硬件支持位移指针,而且该指针从未用来指向该 GC 堆,则也可以使用它
们。
• 不要使用“一个字节一个字节的”内存复制方式来复制指针值。这样可能会导致中间
条件,到时就没有合法的指针了;而且如果 GC 在此种条件下暂停线程的话,那么它
就会搞乱内存。大部分的 memcpy() 实现是可以工作的,因为它的内部实现完成的
是以排列块大于或等于一个指针大小的方式进行的复制,不过由于 C 标准并不担保
此种实现,因此在使用 memcpy() 时应特别小心。
可靠且可以完成的事情:
• 使用联合共享指针的存储空间:
union U { void* ptr; int value }
• 如果存在指向垃圾回收对象对象内部的指针,就不必维护指向对象开始处的指针。
char[] p = new char[10];
char[] q = p[3..6];
// q 完全可以用来指向整个对象,不需要同时
// 保留 p 。
程序员可以不用指针完成大部分任务。D 提供的各种特征使得人们在决大多数情况下都不需
要显式地使用指针,这些特征包括:引用对象、动态数组和垃圾回收。提供指针的目的是成
功地同 C API 衔接并完成一些低级的工作。
22.4 与垃圾回收程序协作
垃圾回收程序并不能解决所有的内存释放问题。例如,如果保留了一个指向一大块数据的指
针,那么就算它再也用不到了,垃圾回收程序也无法回收这块空间。为了解决这个问题,一
个不错的实际操作就是:在某个对象不再使用时将指向它的引用或指针设置为 null。
这个建议只适用于静态引用或者嵌入到其他对象内的引用。它对于那些存储在堆栈上的引用
没什么意义,因为回收程序并不扫描栈顶之上的部分,并且新的堆栈帧总会被初始化。
22.5 参考
• Wikipedia
• GC 问与答
• 统一处理器——垃圾回收器技术
• 垃圾回收:自动的动态内存管理算法
发表评论
-
土耳其文《d编程》range 翻译 一
2011-11-15 02:01 1525Ranges 范围 Ranges are an abstra ... -
土耳其文《d编程》range 翻译 二
2011-11-15 01:59 1020As you can see, that output doe ... -
d2 range 和 标准C++中的Iterator(迭代器)简介
2011-05-07 12:59 2142原文: http://hi.baidu.com/c ... -
三访安德烈Alexandrescu(第2部)
2010-08-20 12:53 1435Google翻译哦 面试------> 应翻成 访谈 ... -
三访安德烈Alexandrescu(第一部分)
2010-08-20 12:43 1357google翻译哦 Interview with Andre ... -
Garden Editor project 日记 之二 10.16 ---
2009-10-16 02:39 02009.10.16 T[new] misgivings ... -
Garden Editor project 日记 之一 09.09.25 --- 10.15
2009-09-24 22:56 0kill two birds with one stone, ... -
template metaprogramming 9
2009-09-09 16:08 1182原文:https://docs.google.co ... -
Floating Point in D (2.030 新)
2009-05-12 23:27 20625.17 23:50 更新 5.16 20:30 翻译更 ... -
Migrating to Shared (2.030 新)
2009-05-12 23:03 11645.19 0:10 更新(完成) ... -
D 2.0 的gc
2008-12-04 19:53 1261http://lucifer1982.wordpress.co ... -
类 class 2.014
2008-06-09 22:51 1106D 的面向对象的特性都来源于类。类层次里的顶层是 Object ... -
接 口 2.014
2008-06-09 22:51 854接口声明: interface 标 ... -
C 语言接口 2.014
2008-06-09 22:50 1040D 的设计就是要在目标系统上能够很好地符合于 C 编译器。D ... -
Traits 特征 2.014
2008-06-07 11:25 12646.14 翻译 (d语言的反 ... -
常量和不变量 Const and Invariant 2.014
2008-06-07 11:22 1322请参考: D 2.0 Const/Final/Invarian ... -
词法 2.014
2008-06-07 10:22 1511在 D 中,词法分析独立于语法分析和语义分析。词法分析器是将源 ... -
枚 举 2.014
2008-06-07 08:41 1167枚举声明: enum 枚举标记 枚举体 enum 枚举体 en ... -
函 数 2 (2.014)
2008-06-07 08:22 10467 嵌套函数 函数可以被 ... -
函 数 2.014
2008-06-07 08:21 1315[size=large]函数体: 块 ...
相关推荐
Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收...
垃圾分类数据集2.4万张(不可回收垃圾和可回收垃圾两类).zip垃圾分类数据集2.4万张(不可回收垃圾和可回收垃圾两类).zip垃圾分类数据集2.4万张(不可回收垃圾和可回收垃圾两类).zip垃圾分类数据集2.4万张(不可回收垃圾...
垃圾分类智能回收系统.pptx
@echo off :start title Purge Subs from %1 call :subpurge %1 FOR /D /R %%a IN (*.*) do call :subpurge "%%a" call :subdel "%%a" :subpurge echo Purging, %1 .........................................
实战大数据扩展视频.zip.014
DXperience-8.3.5.zip.014
6. 大块骨头和牡蛎壳属于厨余垃圾,可以进行堆肥处理,而不是可回收垃圾、有害垃圾或不可回收垃圾。 7. 可堆肥垃圾的垃圾桶通常是绿色的,用于收集厨余垃圾和其他可生物降解的有机废物。 8. 可回收垃圾的垃圾桶是...
2. 分类:按照垃圾的性质和处理方式将其分为不同类别,如可回收物、湿垃圾(厨余)、干垃圾(其他)、有害垃圾等。 3. 收集:指将分散的垃圾集中到特定容器或地点的过程。 4. 清运:将收集好的垃圾定期或按需运输至...
自己总结的jvm中垃圾回收相关概念的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
自己总结的jvm中内存和垃圾回收的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
一个常见垃圾病毒清理工具.很好用的.一个常见垃圾病毒清理工具.很好用的.一个常见垃圾病毒清理工具.很好用的.一个常见垃圾病毒清理工具.很好用的.一个常见垃圾病毒清理工具.很好用的.一个常见垃圾病毒清理工具.很...
22丨如何优化垃圾回收机制?.html
易语言源码易语言生成垃圾文件源码.rar 易语言源码易语言生成垃圾文件源码.rar 易语言源码易语言生成垃圾文件源码.rar 易语言源码易语言生成垃圾文件源码.rar 易语言源码易语言生成垃圾文件源码.rar 易语言源码...
2. 资源回收:通过垃圾分类,可回收物如纸张、塑料、玻璃、金属等可以被再利用,减少了对新资源的需求,有利于可持续发展。 3. 环保意识:这些标语强调了垃圾分类对环境保护的重要性,提醒人们应该承担起保护环境的...
Java城市垃圾分类回收管理系统源码.zip 该项目是个人大作业项目源码,评审分达到98分,都经过严格调试,确保可以运行!放心下载使用。 Java城市垃圾分类回收管理系统源码.zip 该项目是个人大作业项目源码,评审分...
2. 数据处理:STM32单片机对采集到的数据进行实时分析,根据预设的垃圾分类规则,判断垃圾是否符合投放要求,并将结果反馈给用户。 3. 用户交互界面:通过LED显示或LCD触摸屏,向用户展示垃圾投放状态,提供直观的...
垃圾调查问卷.pdf
生活垃圾热解技术.pdf
2. **环境危害**:垃圾堆积不仅侵占土地,还会导致土壤污染,影响农作物生长。同时,垃圾中的有害物质如重金属会渗透到地下水,污染水源,对人类健康构成潜在威胁。 3. **空气污染**:焚烧垃圾作为一种处理方式,...
垃圾分类标志.ppt