gpt4 book ai didi

raku - Nativecall Buf 生命周期和垃圾收集器

转载 作者:行者123 更新时间:2023-12-04 14:53:54 24 4
gpt4 key购买 nike

我在 Buf 中有一大块内存我想传递给 C 库,但该库将使用超出单个调用生命周期的内存。

我知道这可能会有问题,因为垃圾收集器可以移动内存。

用于传递 Str , Nativecall docs
说“如果 C 函数需要字符串的生命周期超过函数调用,则必须手动编码参数并作为 CArray[uint8] 传递”,并有一个这样做的例子,基本上:

my $array = CArray[uint8].new($string.encode.list);

我的问题是:我必须为 Buf 做同样的事情吗? ?万一它被GC移动了?还是GC会离开我的 Buf它在哪里?对于短字符串,这没什么大不了的,但对于大内存缓冲区,这可能是一项昂贵的操作。 (例如,参见 Archive::Libarchive,您可以将 Buf 与 tar 文件一起传递。该代码有问题吗?
multi method open(Buf $data!) {
my $res = archive_read_open_memory $!archive, $data, $data.bytes;
...

有(可能有吗?应该有吗?)某种 traitBuf告诉GC不要移动它?我知道如果我将更多数据添加到 Buf 可能会很麻烦。 ,但我保证不会那样做。 Blob 怎么样?那是不可变的?

最佳答案

如果您保留对 Blob 的引用,至少目前您可以在 MoarVM 上解决这个问题。或 Buf只要 native 代码需要它,并且(在 Buf 的情况下)你不会对它进行可能导致调整大小的写入,它就在 Perl 6 中存在。

MoarVM 分配 Blob/Buf在 Nursery 内的对象,并且会在 GC 运行期间移动它。但是,该对象不保存数据;相反,它保存大小和指向保存值的内存块的指针。该内存块未使用 GC 分配,因此不会移动。

+------------------------+
| GC-managed Blob object |
+------------------------+ +------------------------+
| Elements |----->| Non-GC-managed memory |
+------------------------+ | (this bit is passed to |
| Size | | native code) |
+------------------------+ +------------------------+

你是否应该依赖这个是一个更棘手的问题。一些考虑:
  • 据我所知,如果在 JVM 上运行,事情可能会不太顺利。我不知道 JavaScript 后端。你可以合理地决定,由于采用水平,你现在只需要担心在 MoarVM 上运行。
  • 如果您只需要自己的代码中的速度,则取决于 MoarVM 的实现细节是可以的,但是如果在您希望被广泛采用的模块上工作,您可能要考虑是否值得。 Rakudo 和 MoarVM 团队都投入了大量工作,以不让模块生态系统中的工作代码回归,即使在可以很好地争论它依赖于错误或未定义行为的情况下也是如此。但是,这可能会阻碍改进。或者,有时,破损被认为是值得的。无论哪种方式,它都非常耗时,并且需要一个志愿者团队。当然,当模块作者响应迅速并且可以应用提供的补丁时,问题就少了一些。

  • “在其上添加特征”的问题在于,决定 - 至少在 JVM 上 - 似乎需要在分配保存数据的内存时预先做出。在这种情况下,可移植解决方案可能不允许现有的 Buf/ Blob被标记为这样。也许更好的方法是要求 I/O 类的东西提供一些东西 CArray -like 相反,因此可以通过首先将数据放在“正确类型的内存”中来实现零拷贝。这可能是一个合理的功能要求。

    关于raku - Nativecall Buf 生命周期和垃圾收集器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55209334/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com