在程序在 C/C++ 中停止之前,是不是曾收回此内存? [复制]

Posted

技术标签:

【中文标题】在程序在 C/C++ 中停止之前,是不是曾收回此内存? [复制]【英文标题】:Is this memory ever claimed back before program stops in C/C++? [duplicate]在程序在 C/C++ 中停止之前,是否曾收回此内存? [复制] 【发布时间】:2014-10-30 00:48:12 【问题描述】:

注意:这是我为了解 C/C++ 中程序和 malloc 的功能而创建的假设情况。

假设我分配了 10k 个整数,它们都在内存中连续分配。现在,我释放了这 10k 个整数中的每个备用元素。现在,我想分配一个需要 8 个字节的长整数。由于上述 5k 个位置都没有连续的 8 个字节,程序是否为这个变量分配了一个新的内存位置?如果将来我将只使用 > 4 字节的位置,那么我只是在浪费整个内存吗?或者编译器是否采取了必要的步骤,以便以后这些剩余的 5k 位置是连续的?

编辑:致那些将其标记为重复的人。 好的,让我们说它使用分页,它通过将页面重新映射到物理内存中的连续块来处理碎片。即使那样,这也意味着在虚拟内存中所有这些地址位置都不再可用,对吧?那么,那些内存位置不可用?是的,我知道这是碎片等问题。我的问题如下:

运行时程序有什么方法可以知道这个问题的出现并以某种方式尝试以一种好的方式管理其资源?由于 C 是一种完全编译的语言,我认为这是不可能的。 JAVA 或 C# 运行时环境会做这样的事情吗?重新组织它们的对象,使它们在堆空间中占用一个连续的内存块?如果发生这种情况,他们是否必须更改每个引用变量的值?因为他们在堆上的位置(以及他们的地址)正在改变?

【问题讨论】:

你是如何分配这些整数的? 它们都在内存中连续分配。你怎么知道的? 你会发现this question值得一读。 一个简单的答案是告诉你你做错了。如果您分配许多相同大小的实例,则使用内存池,而不是 malloc/new。 回答你的新问题,是的。这就是所谓的垃圾收集器。有许多不同类型的垃圾收集算法,但压缩是非常常见的实现。您也可以用 C 语言编写代码来执行此操作。但是你不能使用原始指针,因为就像你说的,它们的地址会改变。您必须使用间接引用。垃圾收集器会维护一个映射表,将这些引用映射为指向实际内存位置的指针。 【参考方案1】:

您的问题的一般答案是您不知道。 C 规范对libc 实现完全开放,malloc 将如何工作。如果它愿意,它可以在内存中完全随机的位置分配这 10k 个整数中的每一个,在这种情况下,在不分配新页面的情况下,肯定会有很多空白需要用 long 来填充。

事实上,在现实世界中,malloc 的实现也有类似的例子。例如,您可能会发现阅读 worst fit 分配器很有趣。

您可能要记住的另一件事是,许多当前的malloc 实现具有它们将在一次调用中分配的最小内存量。在 x86-64glibc 上,这个数量是 24 字节,所以无论你调用它分配 4 字节还是 8 字节,仍然会分配 24 字节。因此,释放这样一个 4 字节的 malloc,仍然可以让 8 字节的 malloc 填充相同的空间。

【讨论】:

以上是关于在程序在 C/C++ 中停止之前,是不是曾收回此内存? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

程序员最容易出现啥问题

在播放 iOS 中的下一首歌曲之前,我是不是需要先停止 MusicPlayerController?

13年程序员打工之路,却从未停止创业!

在退出之前跟踪 - 并正确结束 - C# - C++/CLI - C++ Windows 窗体应用程序中的本机和托管线程

你好我曾遇到同样的问题,java编写的windows服务程序,启动时会立刻停止服务无法正常启动你是怎么解决的

push_back() 导致程序在进入 main() 之前停止