Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是内存碎片? 我听说过“内存碎片”这个术语在C++动态内存分配的上下文中使用过几次。我发现了一些关于如何处理内存碎片的问题,但找不到一个直接解决它本身的问题。因此: 什么是内存碎片 如何判断内存碎片是否是我的应用程序的问题?什么样的项目最有可能受到影响 处理内存碎片的常用方法有哪些_C++_Memory_Heap_Fragmentation - Fatal编程技术网

什么是内存碎片? 我听说过“内存碎片”这个术语在C++动态内存分配的上下文中使用过几次。我发现了一些关于如何处理内存碎片的问题,但找不到一个直接解决它本身的问题。因此: 什么是内存碎片 如何判断内存碎片是否是我的应用程序的问题?什么样的项目最有可能受到影响 处理内存碎片的常用方法有哪些

什么是内存碎片? 我听说过“内存碎片”这个术语在C++动态内存分配的上下文中使用过几次。我发现了一些关于如何处理内存碎片的问题,但找不到一个直接解决它本身的问题。因此: 什么是内存碎片 如何判断内存碎片是否是我的应用程序的问题?什么样的项目最有可能受到影响 处理内存碎片的常用方法有哪些,c++,memory,heap,fragmentation,C++,Memory,Heap,Fragmentation,此外: 我听说经常使用动态分配会增加内存碎片。这是真的吗?在C++环境下,我理解所有标准容器(STD::String,STD::vector等)使用动态内存分配。如果这些在整个程序中使用(特别是std::string),内存碎片更可能成为问题吗 如何在STL密集型应用程序中处理内存碎片 什么是内存碎片? 内存碎片是指大部分内存被分配到大量非连续块或块中,导致大部分内存未分配,但在大多数典型情况下无法使用。这会导致内存不足异常或分配错误(即malloc返回null) 考虑这一点最简单的方法是想

此外:

  • 我听说经常使用动态分配会增加内存碎片。这是真的吗?在C++环境下,我理解所有标准容器(STD::String,STD::vector等)使用动态内存分配。如果这些在整个程序中使用(特别是std::string),内存碎片更可能成为问题吗
  • 如何在STL密集型应用程序中处理内存碎片
什么是内存碎片?

内存碎片是指大部分内存被分配到大量非连续块或块中,导致大部分内存未分配,但在大多数典型情况下无法使用。这会导致内存不足异常或分配错误(即malloc返回null)

考虑这一点最简单的方法是想象你有一个巨大的空墙,你需要把不同大小的图片放在上面。每张照片都有一定的尺寸,很明显,你不能把它分割成更小的部分,以使其适合。你需要在墙上有一个空的地方,图片的大小,否则你不能把它挂起来。现在,如果你开始把图片挂在墙上,而你不注意如何排列它们,你很快就会看到墙上部分覆盖着图片,即使你可能有空的斑点,但大多数新图片都不适合,因为它们比可用的斑点大。你仍然可以挂很小的图片,但大多数都不适合。因此,你必须重新排列(压缩)墙上已有的,以腾出空间容纳更多的

现在,假设墙是你的(堆)内存,图片是对象。。这是内存碎片

如何判断内存碎片是否是我的应用程序的问题?什么样的项目最有可能受到影响?

有一个迹象表明,你可能正在处理内存碎片问题,那就是如果你有很多分配错误,特别是当使用内存的百分比很高时——但不是你还没有用完所有内存——所以从技术上讲,你应该有足够的空间来分配你试图分配的对象

当内存严重碎片化时,内存分配可能需要更长的时间,因为内存分配器必须做更多的工作才能为新对象找到合适的空间。如果依次有许多内存分配(可能是因为内存碎片而分配的),分配时间甚至可能会导致明显的延迟

处理内存碎片的常用方法有哪些?


使用一个好的算法来分配内存。与其为许多小对象分配内存,不如为这些小对象的连续数组预先分配内存。有时,在分配内存时有点浪费可以提高性能,并且可以省去处理内存碎片的麻烦。

当您分配和取消分配许多大小不同的对象时,最有可能发生内存碎片。假设内存中有以下布局:

obj1 (10kb) | obj2(20kb) | obj3(5kb) | unused space (100kb)
现在,当释放
obj2
时,您有120kb的未使用内存,但无法分配120kb的完整块,因为内存是碎片化的

避免这种影响的常用技术包括和。在STL的上下文中,类似的方法可以提供帮助

什么是内存碎片

当你的应用程序使用动态内存时,它会分配和释放内存块。开始时,应用程序的整个内存空间是一个连续的可用内存块。但是,当您分配和释放不同大小的块时,内存开始变得碎片化,即,不是一个大的连续空闲块和许多连续的已分配块,而是一个已分配块和空闲块混合在一起。由于空闲块的大小有限,因此很难重用它们。例如,您可能有1000字节的可用内存,但无法为100字节块分配内存,因为所有可用块的长度最多为50字节

另一个不可避免但问题较少的碎片来源是,在大多数体系结构中,内存地址必须与2、4、8等对齐。字节边界(即地址必须是2、4、8等的倍数)这意味着,即使您有一个包含3个
char
字段的结构,由于每个字段都与4字节边界对齐,因此结构的大小可能为12而不是3

如何判断内存碎片是否是我的应用程序的问题?什么样的项目最有可能受到影响

显而易见的答案是,您会遇到内存不足异常

显然,没有一种好的便携方式来检测C++应用程序中的内存碎片。有关更多详细信息,请参阅

处理内存碎片的常用方法有哪些

在C++中很困难,因为在指针中使用直接内存地址,并且无法控制谁引用特定的内存地址。因此,重新排列分配的内存块(就像Java垃圾收集器那样)不是一个选项

自定义分配器可以帮助管理较大内存块中小对象的分配,并重用该内存块中的可用插槽。

想象一下,您有一个“大”(32字节)的可用内存:

----------------------------------
|                                |
----------------------------------
现在,分配一些(5次分配):

现在,释放前四次分配,但不释放第五次分配:

----------------------------------
|              eeee              |
----------------------------------
现在,,
----------------------------------
|              eeee              |
----------------------------------
----------------------------------
|ffffffffffffffeeeeff            |
----------------------------------
------------------------------------------------------...
|              eeeeffffffffffffffff                   
------------------------------------------------------...
 |   |   |   |   |   |   |   |   |   |   |
   0   1   2   3   4   5   6   7   8   9
 | A | A | A | B | B | B | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9
 | A | A | A |   |   |   | C | C | C |   |
   0   1   2   3   4   5   6   7   8   9