Memory management 如何使用Nim在堆栈上开发?

Memory management 如何使用Nim在堆栈上开发?,memory-management,garbage-collection,nim-lang,stack-memory,Memory Management,Garbage Collection,Nim Lang,Stack Memory,我希望在软实时上下文中使用Nim,在软实时上下文中,内存分配和垃圾收集都会表现出太多的延迟。因此,手动内存管理是可取的——或者更好的是,完全从堆栈内存工作 为了实现仅堆栈的内存分配,我可以使用Nim的哪个子集?我猜我可以通过在缓存的C代码中没有memset或memcpy来判断它是否有效。如果您真的想不进行垃圾收集,您需要将--gc与none参数一起使用,如中所述。none参数禁用垃圾收集器,让您自己处理。这通常意味着任何字符串操作都会产生警告,因为尽管分配了内存,但以后没有人释放它: proc

我希望在软实时上下文中使用Nim,在软实时上下文中,内存分配和垃圾收集都会表现出太多的延迟。因此,手动内存管理是可取的——或者更好的是,完全从堆栈内存工作


为了实现仅堆栈的内存分配,我可以使用Nim的哪个子集?我猜我可以通过在缓存的C代码中没有memset或memcpy来判断它是否有效。

如果您真的想不进行垃圾收集,您需要将
--gc
none
参数一起使用,如中所述。
none
参数禁用垃圾收集器,让您自己处理。这通常意味着任何字符串操作都会产生警告,因为尽管分配了内存,但以后没有人释放它:

proc main() =
  let x = 5
  echo "Hello " & $x & " there"

main()
如果您使用
nimc--gc:none-r test.nim编译这个小测试,您将得到gc警告:

test.nim(3, 19) Warning: '$ x' uses GC'ed memory [GcMem]
test.nim(3, 22) Warning: '&("Hello ", $ x, " there")' uses GC'ed memory [GcMem]
这可以帮助您直接或间接地了解Nim的哪些部分可以在无GC的环境中安全使用。但是,请注意,某些操作可以移动到编译阶段。因此,下面的示例在不使用GC的情况下生成相同的输出是安全的,因为所有的
const
表达式都是由生成的C代码静态分配的:

proc main() =
  const x = 5
  echo "Hello " & $x & " there"

main()
查看
nimcache
目录,您会发现源代码包含一行类似于以下内容的内容:

  STRING_LITERAL(TM_ipcYmBC9bj9a1BW35ABoB1Kw_2, "Hello 5 there", 13);

不过,请注意,在上述文档中有一个指向文档的链接,其中包含一个非常具体的实时支持部分,可能会有所帮助,如果它提供的折衷方案符合您的要求,则可能会避免手动处理内存的痛苦。

目前,字符串和seq类型都需要GC才能正常工作,即使它们具有值类型语义。然而,计划对此进行更改。我只是不能告诉你这是什么时候。如果没有这两种类型,Nim就不是您真正想要使用的语言。除了那些类型,WROK在C++中非常相似。因此,如果您不使用
ref
类型,那么GC将不会有进一步的分配。

不是Nim规范,也不是GC规范,我也不会在这里提供合理的答案,而是语言无关的编程建议

该堆栈仅限于一个MiB或Android上的24KiB。您可以通过左右调整清单使其达到8MB

如果您没有操作系统,在真实模式和非虚拟化内存空间中,可能会有一个无限的堆栈

但现实世界中的大多数应用程序都必须使用分配器。在堆上保留一块内存,并保留一个自定义的“堆栈指针”,您可以手动递增/递减,而不是让编译器来执行

这带来了两个优点:与调用堆栈和块作用域分离。无限的记忆

限制:在linux上,您的页面将按需零填充。内核延迟提供页面,因此您将在关键时刻遇到口吃。为了避免这种情况,请在整个空间上准备一次写入0xff的扫描过程。 这样做的缺点是与其他进程的协作性差,可能会破坏文件系统缓存。但对于用户通常接受的实时应用程序