draveness/blog-comments

内存管理设计精要 - 面向信仰编程 · /system-design-memory-management

draveness opened this issue · 26 comments

好文!

typo:(栈内存)不过我们也只能在栈上分配「大续爱」固定的数据结构。

疑似typo:(删除写屏障)This guarantees that no objects will become unreachable to the garbage collector traversal 「�」all objects which are live at the beginning of garbage collection will be reached even if the pointers to them are overwritten.


2021-02-28 UPDATES: 已修复

好文!

typo:(栈内存)不过我们也只能在栈上分配「大续爱」固定的数据结构。

疑似typo:(删除写屏障)This guarantees that no objects will become unreachable to the garbage collector traversal 「�」all objects which are live at the beginning of garbage collection will be reached even if the pointers to them are overwritten.

修复啦,感谢

好文!感谢分享。
此外,我有问题想请教下。
像文中这些为了垃圾回收而构造的结构体会被储存在哪个块内存区域呢?

@Jun10ng 好文!感谢分享。
此外,我有问题想请教下。
像文中这些为了垃圾回收而构造的结构体会被储存在哪个块内存区域呢?

这个要看编程语言怎么设计,有的结构会与分配的内存存储在一起,有的会开辟独立的空间存储

jinze commented

把GC都讲全面了。期待作者也能讲讲rust和c++,这个题目就覆盖完整了。

感谢分享!

https://img.draveness.me/2021-02-28-16145096643079-tri-color-mark-sweep.png

这张图中三色标记 F->G 的变色过程是不是只进行了一次,后面应该全部标记黑吧

感谢分享!

https://img.draveness.me/2021-02-28-16145096643079-tri-color-mark-sweep.png

这张图中三色标记 F->G 的变色过程是不是只进行了一次,后面应该全部标记黑吧

是的,这里没有展示全部的标记过程

一个小建议,这篇文章前几个图宽度比较小没有居中对其,看着有些难受

还是这种图的风格看得比较习惯自然

能解释一下为什么 moving 的垃圾收集器,它不适用于 C、C++ 等编程语言 吗 谢谢

能解释一下为什么 moving 的垃圾收集器,它不适用于 C、C++ 等编程语言 吗 谢谢

C 和 C++ 是可以直接拿到裸指针的,moving 会移动对象存储的位置可能造成潜在的问题

想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

EDIT: 之前的回复有一些问题,如果 A 原来指向 B 现在指向 C,那么 B 对象会被涂成灰色

“图 4 - 内存布局” 是不是有点问题,虚拟内存怎么可能只有 4G 呢?

“图 4 - 内存布局” 是不是有点问题,虚拟内存怎么可能只有 4G 呢?

这里仅展示了内存的几个不同区

@draveness

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

我也对这里很疑惑,文中提到的删除写机制是

上述代码会在老对象的引用被删除时,将白色的老对象涂成灰色,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用

writePointer(slot, ptr)
    shade(*slot)
    *slot = ptr

我理解是说删除写屏障是在引用被删除的时候触发,这里没有引用被删除,也就没法触发删除写屏障,为什么A会被标记成灰色?是否这里还有文中没提到的逻辑,比如shade(*slot)里会判断如果*slot是空,就把当前对象(A)改成灰色

还有一点楼上同学提到的,假如B没有指向C,C没有被任何对象引用,然后突然被A引用了,其实我对这种行为也不解,因为C是完全不可达了,怎么还会通过某种方式被A引用,这种情况是否可能呢,也希望解答一下,我想到情形是突然创建了一个对象F然后被A引用了,这种删除写屏障怎么处理呢,求大佬解答,谢谢🙏

@draveness

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

抱歉,之前的回复有一些问题,如果 A 原来指向 B 现在指向 C,那么 B 对象会被涂成灰色

我也对这里很疑惑,文中提到的删除写机制是

上述代码会在老对象的引用被删除时,将白色的老对象涂成灰色,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用

writePointer(slot, ptr)
    shade(*slot)
    *slot = ptr

我理解是说删除写屏障是在引用被删除的时候触发,这里没有引用被删除,也就没法触发删除写屏障,为什么A会被标记成灰色?是否这里还有文中没提到的逻辑,比如shade(*slot)里会判断如果*slot是空,就把当前对象(A)改成灰色

还有一点楼上同学提到的,假如B没有指向C,C没有被任何对象引用,然后突然被A引用了,其实我对这种行为也不解,因为C是完全不可达了,怎么还会通过某种方式被A引用,这种情况是否可能呢,也希望解答一下,我想到情形是突然创建了一个对象F然后被A引用了,这种删除写屏障怎么处理呢,求大佬解答,谢谢🙏

这个场景是冲突的,如果 C 没有被任何对象引用是不能被 C 拿到的,既然能够拿到 C 的指针,那说明有对象指向 C

@draveness

@draveness

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

抱歉,之前的回复有一些问题,如果 A 原来指向 B 现在指向 C,那么 B 对象会被涂成灰色

我也对这里很疑惑,文中提到的删除写机制是

上述代码会在老对象的引用被删除时,将白色的老对象涂成灰色,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用

writePointer(slot, ptr)
    shade(*slot)
    *slot = ptr

我理解是说删除写屏障是在引用被删除的时候触发,这里没有引用被删除,也就没法触发删除写屏障,为什么A会被标记成灰色?是否这里还有文中没提到的逻辑,比如shade(*slot)里会判断如果*slot是空,就把当前对象(A)改成灰色

还有一点楼上同学提到的,假如B没有指向C,C没有被任何对象引用,然后突然被A引用了,其实我对这种行为也不解,因为C是完全不可达了,怎么还会通过某种方式被A引用,这种情况是否可能呢,也希望解答一下,我想到情形是突然创建了一个对象F然后被A引用了,这种删除写屏障怎么处理呢,求大佬解答,谢谢🙏

这个场景是冲突的,如果 C 没有被任何对象引用是不能被 C 拿到的,既然能够拿到 C 的指针,那说明有对象指向 C

明白了,那对于新创建的对象F,然后被A引用了这种情况呢,因为F新创建出来是白色,然后被黑色的A引用了,这里没有老对象的引用被删除,删除写屏障怎么解决这个问题

@draveness

@draveness

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

抱歉,之前的回复有一些问题,如果 A 原来指向 B 现在指向 C,那么 B 对象会被涂成灰色

我也对这里很疑惑,文中提到的删除写机制是

上述代码会在老对象的引用被删除时,将白色的老对象涂成灰色,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用

writePointer(slot, ptr)
    shade(*slot)
    *slot = ptr

我理解是说删除写屏障是在引用被删除的时候触发,这里没有引用被删除,也就没法触发删除写屏障,为什么A会被标记成灰色?是否这里还有文中没提到的逻辑,比如shade(*slot)里会判断如果*slot是空,就把当前对象(A)改成灰色
还有一点楼上同学提到的,假如B没有指向C,C没有被任何对象引用,然后突然被A引用了,其实我对这种行为也不解,因为C是完全不可达了,怎么还会通过某种方式被A引用,这种情况是否可能呢,也希望解答一下,我想到情形是突然创建了一个对象F然后被A引用了,这种删除写屏障怎么处理呢,求大佬解答,谢谢🙏

这个场景是冲突的,如果 C 没有被任何对象引用是不能被 C 拿到的,既然能够拿到 C 的指针,那说明有对象指向 C

明白了,那对于新创建的对象F,然后被A引用了这种情况呢,因为F新创建出来是白色,然后被黑色的A引用了,这里没有老对象的引用被删除,删除写屏障怎么解决这个问题

垃圾收集期间创建的对象都会是黑色的

@draveness

@draveness

@draveness

@longyuxiao 想问一下为什么说读屏障对性能影响很大, 读写屏障不都是要插入代码的吗

因为读屏障触发的时机更多

@vegchic 删除写屏障里那个例子,如果 B 原本就没有指向 C,A(黑色) 突然指向 C(白色),怎么保证 C 不被回收呢,还是说三色标记时“将黑色对象指向的所有对象都标记成灰色”指的是已有的所有黑色对象?

A 会被标记成灰色

抱歉,之前的回复有一些问题,如果 A 原来指向 B 现在指向 C,那么 B 对象会被涂成灰色

我也对这里很疑惑,文中提到的删除写机制是

上述代码会在老对象的引用被删除时,将白色的老对象涂成灰色,这样删除写屏障就可以保证弱三色不变性,老对象引用的下游对象一定可以被灰色对象引用

writePointer(slot, ptr)
    shade(*slot)
    *slot = ptr

我理解是说删除写屏障是在引用被删除的时候触发,这里没有引用被删除,也就没法触发删除写屏障,为什么A会被标记成灰色?是否这里还有文中没提到的逻辑,比如shade(*slot)里会判断如果*slot是空,就把当前对象(A)改成灰色
还有一点楼上同学提到的,假如B没有指向C,C没有被任何对象引用,然后突然被A引用了,其实我对这种行为也不解,因为C是完全不可达了,怎么还会通过某种方式被A引用,这种情况是否可能呢,也希望解答一下,我想到情形是突然创建了一个对象F然后被A引用了,这种删除写屏障怎么处理呢,求大佬解答,谢谢🙏

这个场景是冲突的,如果 C 没有被任何对象引用是不能被 C 拿到的,既然能够拿到 C 的指针,那说明有对象指向 C

明白了,那对于新创建的对象F,然后被A引用了这种情况呢,因为F新创建出来是白色,然后被黑色的A引用了,这里没有老对象的引用被删除,删除写屏障怎么解决这个问题

垃圾收集期间创建的对象都会是黑色的

明白了,谢谢!

语义垃圾是不会被使用的的对象,可能包括废弃的内存、不使用的变量,垃圾收集器无法解决程序中语义垃圾的问题,我们需要通过编译器来一部分语义垃圾。

少了个动词。回收?处理?


2021-07-02: UPDATES 已修复

mnff commented

文中“语义垃圾是不会被使用的的对象,垃圾收集器无法解决程序中语义垃圾的问题,语法垃圾是在对象图中不能从根节点达到的对象,所以语法垃圾在一般情况下都是语义垃圾”,这里是不是有点问题,gc是可以处理不可达对象的

文中“语义垃圾是不会被使用的的对象,垃圾收集器无法解决程序中语义垃圾的问题,语法垃圾是在对象图中不能从根节点达到的对象,所以语法垃圾在一般情况下都是语义垃圾”,这里是不是有点问题,gc是可以处理不可达对象的

这里的理解是有问题的,语义垃圾可以理解为类中不会使用的变量等,这些垃圾回收处理不了

image

这是图片位置不对吗,还是书写错误🐶

删除写屏障 那里有点疑惑: A->b->c => A->B=nil 此时将c还去标记是不是算误标呢?