混合GC内存和 ptr
要特别注意的是,如果一个未被追踪的对象包含被追踪的对象,例如包含追踪的引用、字符串、序列。为了正确释放所有对象, 在释放未被追踪的内存之前,需要手动调用内置过程 reset :
type
Data = tuple[x, y: int, s: string]
# 在堆上为 Data 分配内存:
var d = cast[ptr Data](alloc0(sizeof(Data)))
# 在垃圾回收(GC)堆上创建一个新的字符串:
d.s = "abc"
# 告知 GC 不再需要这个字符串:
reset(d.s)
# 释放内存:
dealloc(d)
如果不调用 reset ,就绝不会释放分配给 d.s 字符串的内存。 这个例子对于程序底层来说,表现出两个重要的特性: sizeof 过程返回一个类型或值的字节大小。 cast 操作符可以避开类型系统: 编译器强制将 alloc0 (会返回一个未定义类型的指针)的结果认定为 ptr Data 类型。 只有在不可避免的情况下才应当进行转换,因为这会破坏类型安全,未知的 bug 可能导致崩溃。
注意: 当把垃圾收集的数据和非管理的内存混合使用时,需要了解这些低级细节。 这个例子之所以有效,是因为 alloc0 将内存初始化为零,而 alloc 不会 。 d.s 被初始化为二进制的零,因而可以处理字符串赋值。
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .