如何用Nim开发堆栈?

时间:2018-02-23 13:46:04

标签: memory-management garbage-collection nim stack-memory

我想在软实时环境中使用Nim,其中内存分配和垃圾收集都表现出太多的延迟。因此,手动内存管理是理想的 - 或者甚至更好,只能从堆栈内存中工作。

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

3 个答案:

答案 0 :(得分:3)

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

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

main()

如果使用nim c --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]

这可以帮助您直接或间接地在无GC环境中捕获Nim的安全部分。但请注意,某些操作可以移动到编译阶段。因此,以下示例生成相同的输出在没有GC的情况下可以安全使用,因为所有const表达式都是由生成的C代码静态分配的:

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

main()

查看nimcache目录,您会发现源代码包含与此类似的行:

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

请注意,在上面提到的文档中,有一个指向Nim's Garbage Collector文档的链接,其中包含一个非常具体的实时支持部分,可能会有所帮助,并且可能会避免如果它提供的妥协符合您的要求,则需要手动处理内存。

答案 1 :(得分:0)

目前,字符串和seq类型都要求GC正常工作,即使它们具有值类型语义。然而,这计划改变。我不能告诉你这是什么时候。如果没有这两种类型,Nim实际上并不是您想要使用的语言。除了类型之外,它几乎与c ++类似。因此,如果您不使用ref类型,则无法为GC进行进一步分配。

答案 2 :(得分:0)

不是Nim的细节,既不是GC的细节,也不是我在这里提供合理的答案,而是与语言无关的编程建议。

在Android上,堆栈是有限的,MiB或24KiB。您可以通过左右调整清单来制作8MiB。

如果您没有操作系统,请使用实模式和非虚拟化的内存空间,也许你将拥有无限的堆栈。

但是大多数真实世界的应用程序都必须使用分配器。在堆上保留一块内存,并保留一个可以手动递增/递减的自定义“堆栈指针”,相比之下通常让编译器执行此操作。

这带来了两个优点:从调用堆栈和块范围中解耦。和无限的记忆。

限制:在Linux上,您的页面将根据需要填充零。内核懒惰地提供页面,因此您将在关键时刻体验到口吃。为避免这种情况,请在整个空间准备一次写入0xff的扫描通道。 这样做的缺点是与其他进程非常不合作,并且可能会破坏文件系统缓存。但对于通常被用户接受的实时应用程序。