【问题标题】:Language without explicit memory alloc/dealloc AND without garbage collection没有显式内存分配/释放和没有垃圾收集的语言
【发布时间】:2011-12-03 14:13:52
【问题描述】:

我想知道是否可以通过在每个作用域的结尾?

明显的问题是,这在每个范围结束时都需要一些时间,但我想知道在当前 CPU 中的所有处理能力和多核情况下,这是否可行。此类语言是否已经存在?

我还想知道,智能指针是唯一可以使用的指针的 C++ 变体是否正是这样一种语言(或者我是否遗漏了一些问题?)。

编辑: 经过更多的研究,显然是这样的:http://en.wikipedia.org/wiki/Reference_counting 我想知道为什么这不是更受欢迎。那里列出的缺点似乎并不严重,根据我的说法,开销应该那么大。一种(非解释,从头开始正确编写)具有 C 系列语法和引用计数的语言对我来说似乎是个好主意。

【问题讨论】:

  • 引用计数的问题是循环引用:如果一个父节点有一个子节点列表并且每个子节点都知道他的父节点,那么整个树将永远不会被释放。
  • 引用计数是一种实现垃圾回收系统的方法。您是在询问不允许任何动态分配的系统,还是询问具有不同于标记和扫描算法的动态分配的系统?
  • 另外,执行内存管理策略最好留给策略决策。像 C 和 C++ 这样的语言可以很好地支持引用计数或其他动态内存管理方案,并且当您想按照自己的方式做事时它们不会妨碍您。如果您使用了强制执行这些策略的语言,那么您迟早需要在某些项目中绕过它们。那么你的语言不能满足你的需求。如果您正在寻找强制执行这些内容,请参阅我的帖子。

标签: pointers memory garbage-collection


【解决方案1】:

引用计数最大的问题是它不是一个完整的解决方案,不能收集循环结构。每次设置引用都会产生开销;对于许多类型的问题,这很快就会增加,并且可能比稍后等待 GC 更糟糕。 (现代的 GC 相当先进而且很棒——不要这样倒数!!!)

【讨论】:

  • 有几种方法可以检测基于引用计数的 GC 中的循环。不过,它们都不便宜。
  • 当您尝试像这样检测这些周期时,您基本上会进行标记扫描收集。
  • 这将是处理该问题的简单方法,但有other solutions
  • 弱引用是作弊:P
  • 现代垃圾收集适用于大多数问题。如果你的服务器有 50GB 的小对象(比如在缓存中),就没有那么多了。扫描堆可能需要 30 秒或更长时间,而且我还没有看到最旧的堆不会锁定整个进程的系统。如果你尝试用 GC 语言实现缓存服务器,GC 期间的延迟会使其完全无法使用。
【解决方案2】:

你所说的没什么特别的,而且一直都在出现。您正在寻找的 C 或 C++ 变体只是普通的常规 C 或 C++。

例如,正常编写程序,但限制自己不要使用任何动态内存分配(没有 new、delete、malloc 或 free 或任何他们的朋友,并确保你的库也这样做),那么你就有了那种系统。您提前计算出您可以做的所有事情需要多少内存,并静态声明该内存(函数级静态变量或全局变量)。编译器以正常的方式处理所有的计算,在每个作用域的末尾没有什么特别的事情发生,也不需要额外的计算。

您甚至可以将运行时环境配置为具有静态分配的堆栈空间(这实际上并不在编译器的控制之下,更多的是链接器和操作系统环境)。只需弄清楚您的函数调用链有多深,以及它使用了多少内存(使用分析器或类似工具),然后在您的链接选项中进行设置。

如果没有动态内存分配(因此不会通过垃圾收集或显式管理进行解除分配),您将受限于您在编写程序时声明的内存。但这没关系,许多程序不需要动态内存,并且已经以这种方式编写。当您绝对肯定需要确切地知道操作将花费多长时间,它将使用多少内存(和其他资源)以及运行时间和使用情况时,嵌入式和实时系统中真正需要这样做这些资源中的一部分永远不会改变。

C 和 C++ 的伟大之处在于,该语言对环境的要求非常低,并为您提供了很多工具,智能指针或静态分配的内存,甚至您梦想的一些特殊方案都可以实施的。要求使用它们,而你对自己施加的限制只是一个政策决定。您可以通过代码审计强制执行该策略(使用脚本扫描源文件或目标文件,并且不允许链接到动态内存库)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    • 2012-04-08
    相关资源
    最近更新 更多