没有垃圾收集器的编程语言:垃圾在哪里?

时间:2017-06-16 10:37:44

标签: c garbage-collection dynamic-memory-allocation

我目前正在研究算法和高级数据结构:因为我熟悉C并且它确实提供了高于实现和指针使用的高级控制,我用它来测试理解迄今为止的主题。

当测试需要像列表和树木这样的恐怖事物的结构时,我问自己:由于C没有垃圾收集器,如果我不调用free()函数来释放所有变量我恐怖地分配,那个记忆在哪里?

其他相关问题包含(抱歉滥用某些条款,我在低级别抽象方面没有太多经验):

  • 编译器是否使用实际的硬盘驱动器资源(如变量位于我的驱动器的x记录中),或者它是" istantiates"用于编译和运行程序的虚拟内存的一部分?

  • 我的硬盘中是否有很多列表,树和图表,所有这些都包含从0到100的数字或字符串" abcd"和" qwerty"?

  • 在格式化驱动器之前,操作系统是否将所述数据识别为垃圾,或者我永远坚持使用此垃圾?

我真的很好奇,我从未低于C级抽象。

6 个答案:

答案 0 :(得分:4)

  

因为C没有垃圾收集器,如果我不调用free()函数来释放我动态分配的所有变量,那个内存会去哪里?

这不是(并且不能真正)由C11标准定义(阅读n1570)。

但是,让我们假装您在一些熟悉的executable(如Linux或Windows或MacOSX)上运行某些C编译器生成的operating system。实际上,您正在运行一些process,其中有一些virtual address space

操作系统virtual memorypagingkernel子系统会使大多数有用pages - resident set size - RAM中的虚拟地址空间并配置MMU;阅读demand paging& thrashing& page cache& page faults

当该进程终止时(通过很好地退出或通过某种异常情况,如segmentation fault),操作系统将释放进程使用的每个资源(包括该进程的虚拟地址空间)。

阅读Operating Systems: Three Easy Pieces了解更多信息。

但是,如果您没有任何操作系统,或者您的操作系统或处理器不支持virtual memory(想到某些Ardunio板),事情可能会大不相同。阅读undefined behaviorruntime systems

答案 1 :(得分:2)

C(以及其他非垃圾收集语言)根本没有垃圾 的概念,因此无需以某种方式收集它 - 要么你持有有效的指向一些已分配的内存,然后它被认为是有价值的内存",或者你没有,那么你的程序是错的 - 它就是那么简单。

后一种情况是C甚至没有进一步评估的事情 - 研究程序中发生的事情是没有意义的,这是错误的"除了修复它。

答案 2 :(得分:0)

如果您没有释放资源,它将保持分配状态。 C编译器对硬盘驱动器一无所知。您可以使用C和相应的IO库读取和写入文件。所以,是的,您的硬盘可能会充斥着运行软件的东西,但C语言或编译器并不负责清理它。你是。您可以手动清理文件,也可以编写C程序以便自行清理。获得一本关于C.的好书。

答案 3 :(得分:0)

C和C ++等语言通过mallocnew等专用函数/运算符使用动态堆分配。这将在RAM中的堆上分配内存。如果这样的程序一旦使用它就无法释放内存,那么程序员就设法创建了一种叫做内存泄漏的错误。这意味着程序现在消耗了无法使用的堆内存,因为程序中没有任何内容指向它。

但是,当进程执行完毕后,操作系统将释放进程分配的所有内存。如果进程无法清理自己的堆分配,操作系统将执行此操作。尽管手动清理内存仍然是一个好习惯,但由于其他原因(暴露潜在的错误)。

因此,内存泄漏的唯一问题是它们会导致程序在执行时占用过多的RAM。一旦进程完成,所有内存 - 包括泄漏的内存 - 都将被释放。

堆和硬盘之间没有任何关系,就像堆栈和硬盘驱动器之间没有关系一样。硬盘驱动器用于存储程序的可执行部分,没有别的。堆,堆栈和其他此类内存区域用于在程序执行时存储数据。由于它们是在RAM中分配的,因此在程序执行完毕后,这些区域中的所有信息都将丢失。

一些语言引入垃圾收集的原因是为了消除内存泄漏的问题。垃圾收集器是一种后台进程,它通过一个程序的堆内存来查找程序中没有任何部分指向的数据段,然后释放这些段。由于垃圾收集器执行此操作,因此不需要free() / delete

由于垃圾收集器需要时不时地执行,因此执行速度很快。这是Java和C#等语言在设计上比C和C ++慢的原因之一。这也是为什么C和C ++不具备垃圾收集器的原因,因为这些语言优先考虑执行速度。

答案 4 :(得分:-1)

在没有本机垃圾收集的C语言中,任何实例化变量都保存在易失性存储器(RAM而不是HDD)中,直到应用程序释放它或应用程序关闭时为止。这可能会导致内存有限的计算机出现严重问题,因为当对象在整个生命周期内没有“处置”时,应用程序的内存分配会持续增长,直到没有内存并且应用程序崩溃并烧毁为止。

在回答第2点和第3点(硬盘上的物体,例如树木,图形)时,不会,它们不会乱丢你的硬盘,因为对象只在内存(RAM)中创建,并且只在应用程序运行时生效,关闭应用程序将释放内存(主要是)供其他应用程序使用。

请参阅此link以获取参考,以帮助更多地理解C变量。

答案 5 :(得分:-2)

你所谈论的那段记忆并没有消失。

它只是保留在那里,并且在分配它的程序完成执行之前,任何其他程序都无法使用它。然后,粗略地说,操作系统来自内存并“清理”该应用程序的所有剩余部分。

建议自己释放内存,因为操作系统的执行方式比任何应用程序都要慢(它必须与其他运行的应用程序交叉检查,以确保它不会释放它不应该是的东西)。