为什么删除的内存无法重用

2024-01-18

我在带有 MSVC 9.0 的 Windows 7 上使用 C++,并且还能够在带有 MSVC 9.0 的 Windows XP SP3 上进行测试和重现。

如果我分配 1 GB 0.5 MB 大小的对象,当我删除它们时,一切正常并且行为符合预期。但是,如果我在删除对象时分配 1 GB 0.25 MB 大小的对象,则内存仍保留保留(黄色地址空间监视器 http://hashpling.org/asm/),从那时起将只能用于小于 0.25 MB 的分配。

这个简单的代码将让您通过更改类型定义的结构来测试这两种情况。分配并删除结构后,它将分配 1 GB 的 1 MB 字符缓冲区,以查看字符缓冲区是否将使用结构曾经占用的内存。

struct HalfMegStruct
{
    HalfMegStruct():m_Next(0){}

    /* return the number of objects needed to allocate one gig */
    static int getIterations(){ return 2048; }

    int m_Data[131071];
    HalfMegStruct* m_Next;
};

struct QuarterMegStruct
{
    QuarterMegStruct():m_Next(0){}

    /* return the number of objects needed to allocate one gig */
    static int getIterations(){ return 4096; }

    int m_Data[65535];
    QuarterMegStruct* m_Next;
};

// which struct to use
typedef QuarterMegStruct UseType;

int main()
{
    UseType* first = new UseType;
    UseType* current = first;

    for ( int i = 0; i < UseType::getIterations(); ++i )
        current = current->m_Next = new UseType;

    while ( first->m_Next )
    {
        UseType* temp = first->m_Next;
        delete first;
        first = temp;
    }

    delete first;

    for ( unsigned int i = 0; i < 1024; ++i )
        // one meg buffer, i'm aware this is a leak but its for illustrative purposes. 
        new char[ 1048576 ]; 

    return 0;
}

下面你可以看到我的结果地址空间监视器 http://hashpling.org/asm/。让我强调一下这两个最终结果之间的唯一区别是分配到 1 GB 标记的结构的大小.

对我来说,这似乎是一个相当严重的问题,许多人可能正在遭受这个问题,但他们甚至不知道这一点。

  • 这是设计使然还是应该被视为错误?
  • 我可以让小的已删除对象实际上可供更大的分配使用吗?
  • 更令人好奇的是,Mac 或 Linux 机器是否也会遇到同样的问题?

我不能肯定地说情况确实如此,但这确实看起来像内存碎片(以多种形式之一)。分配器(malloc)可能会保留不同大小的存储桶以实现快速分配,在释放内存后,它不会直接将其返回给操作系统,而是保留存储桶,以便可以从以后处理相同大小的分配。相同的记忆。如果是这种情况,则该内存将可用于相同大小的进一步分配。

这类优化,通常被禁用big对象,因为它需要保留即使没有使用内存。如果阈值介于两个尺寸之间,则可以解释该行为。

请注意,虽然您可能认为这很奇怪,但在大多数程序(不是测试,而是现实生活)中,内存使用模式都是重复的:如果您一次请求 100k 块,那么您通常会再次这样做。并保留记忆reserved可以提高性能并且实际上reduce来自同一存储桶授予的所有请求的碎片。

如果您想投入一些时间,可以通过分析行为来了解分配器的工作原理。编写一些测试,将获取大小 X,释放它,然后获取大小 Y,然后显示内存使用情况。修复 X ​​的值并使用 Y。如果从相同的存储桶授予两种大小的请求,您将不会有保留/未使用的内存(左图),而当从不同的存储桶授予大小时,您将看到右图的效果。

我通常不会为 Windows 编写代码,而且我什至没有 Windows 7,所以我不能肯定地说情况就是如此,但看起来确实如此。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么删除的内存无法重用 的相关文章

  • 是否需要销毁运算符删除的形式才能真正销毁对象?

    C 20 添加了破坏形式operator delete区别于std destroying delete t范围 它导致delete表达式在调用之前不再销毁对象operator delete 目的是在显式调用对象的析构函数和释放内存之前 允许
  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • 为什么 C 程序使用 Scanf 给出奇怪的输出?

    我目前正在学习 C 编程 并且遇到了这个奇怪的输出 Program will try functionalities of the scanf function include
  • 在 C 语言中,为什么数组的地址等于它的值?

    在下面的代码中 指针值和指针地址与预期不同 但数组值和地址则不然 怎么会这样 Output my array 0022FF00 my array 0022FF00 pointer to array 0022FF00 pointer to a
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • 使用 C# 和 ASP.NET 在电子邮件附件中发送 SQL 报告

    我正在尝试使用 ASP NET 和 C 从 sql reportserver 2008 作为电子邮件附件发送报告 到目前为止我学会了如何获取 PDF 格式的报告 http weblogs asp net srkirkland archive
  • 测量进程消耗的 CPU 时钟

    我用 C 语言编写了一个程序 它是作为研究结果创建的程序 我想计算程序消耗的确切 CPU 周期 精确的循环次数 知道我怎样才能找到它吗 The valgrind tool cachegrind valgrind tool cachegrin
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 读取依赖步行者输出

    I am having some problems using one of the Dlls in my application and I ran dependency walker on it i am not sure how to
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • Xamarin Forms Binding - 访问父属性

    我无法访问页面的 ViewModel 属性以便将其绑定到 IsVisible 属性 如果我不设置 BindingContext 我只能绑定它 有没有办法可以在设置 BindingContext 的同时访问页面的 viewmodel root
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如何从 Windows Phone 7 模拟器获取数据

    我有一个 WP7 的单元测试框架 它在手机上运行 结果相当难以阅读 因此我将它们写入 XDocument 我的问题是 如何才能将这个 XML 文件从手机上移到我的桌面上 以便我可以实际分析结果 到目前为止 我所做的是将 Debugger B
  • 任何人都可以清楚地告诉如何在不使用像 这样的预定义函数的情况下找到带有小数值或小数值的指数吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 例如 2 0 5 1 414 所以想要 我是 c 的新手 所以请解释简单的逻辑 如果不是复杂的逻辑也足够了 在数学中 从整数取幂到实数
  • 如何组合两个 lambda [重复]

    这个问题在这里已经有答案了 可能的重复 在 C 中组合两个 lambda 表达式 https stackoverflow com questions 1717444 combining two lamba expressions in c
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐

  • 如何将 malloc 返回的指针视为多维数组?

    有没有办法告诉编译器我已经分配了大小为 N M 的内存 并且我想将此指针视为 N M 数组 换句话说 有没有办法写这样的东西 int arr N M int N M malloc N M sizeof int arr x y 123 我知道
  • Java 7 明显的安全变化

    随着最近对 Java 7s 安全检查的更改 我正在更新我们的 Webstart 应用程序 以允许它在没有警告的情况下运行 我们的 webstart 应用程序由许多 jar 文件组成 其中只有少数是我们开发的 我们使用许多第 3 方 jar
  • 从node.js中的模块内调用app.js的函数?

    假设我有以下 app js 显然very简化 var express require express app express createServer include routes require lib routes app some r
  • 如何抓取由 R 渲染的 JavaScript 网站?

    想问下有没有什么好的方法可以抓取下面的网站 基本上我想获取所有产品的名称和价格 然而 价格信息存储在一些 JQuery 脚本中 硒是唯一的解决方案吗 想过用V8 Jsonlite 但好像不太适用 如果你能在 R 中提供一些替代方案 那就太好
  • Ansible playbook 中的动态变量名称?

    我有许多带有名称的列表 这些列表是通过附加创建的ec2 public dns name to seeds 像这样 seeds ec2 50 8 1 43 us west 1 compute amazonaws com 我需要每个主机的配置来
  • 如何在 Vertica 中创建外部过程

    如何在 Vertica 中创建使用带有诸如以下子句的 SQL 的函数 过程FROM WHERE GROUP BY ORDER BY LIMIT etc 维蒂卡的create function语法禁止在语句中使用某些子句expression
  • Excel VBA Array() 函数导致类型不匹配?

    我创建了以下函数来查找文件并在未找到文件时给出错误 Public Function checkFileExistence arrFileNames As String Optional bShowErrMsg As Boolean Fals
  • Python SIGINT 未捕获

    我不明白为什么我的 SIGINT 永远不会被下面的代码捕获 usr bin env python from threading import Thread from time import sleep import signal class
  • 如何让主线程等待所有子线程完成?

    我打算在主线程中触发 2 个线程 并且主线程应该等待所有 2 个子线程完成 这就是我的做法 void routine void arg sleep 3 int main for int i 0 i lt 2 i pthread t tid
  • v3io,文件数量限制

    您知道限制或公式吗 如何计算 v3io 中的文件数量 它可能与集群中数据节点的数量和数据服务器节点上的内存大小有关 我尝试在 v3io 中使用 50 个和 8000 万个文件 它表现良好 但了解预期限制或一般建议很重要 顺便说一句 我没有这
  • 如何使用线程模块暂停和恢复线程?

    我有一个很长的进程 我计划在一个线程中运行 因为否则它会冻结我的 wxpython 应用程序中的 UI 我在用着 threading Thread target myLongProcess start 启动线程并且它可以工作 但我不知道如何
  • common lisp - 获取文件路径

    在 Common Lisp 中 有没有办法获取编译文件的路径 类似于当前目录 该文件不在当前目录文件夹内 这应该是一条评论 但我将提供一些可能对原始发布者有所帮助的代码示例 首先 你需要更清楚自己想做什么 您想要解决的问题是什么 其次 这里
  • 对于 Web 应用程序来说,正确的 MVC 图是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 哪个 MVC 图是正确的 每个都有不同的箭头 图1 图2 source stannard net au http blog stannard n
  • 为什么“map (filter fst)”的类型为“[[(Bool, a)]] -> [[(Bool, a)]]”?

    我试图理解为什么这个函数 map filter fst 有类型 Bool a gt Bool a 如果filter必须接收一个返回Bool类型的函数并且fst只返回元组的第一个元素 那么 filter fst 如何工作 filter a g
  • 将桌面拖放到浏览器 HTML5 Javascript [重复]

    这个问题在这里已经有答案了 正在寻找一些指导 仍然是一个代码学习者 并且在使用 HTML5 DnD File Api 时遇到了一些困难 玩了一些演示 尝试了解它们是如何工作的 我有一点问题 大多数似乎使用内联 css js 方法 我试图在单
  • 将 JPG 转换为 Base64 并返回 [重复]

    这个问题在这里已经有答案了 我可以使用以下 PowerShell 命令将 jpeg 转换为 base64 字符串 Convert ToBase64String Get Content Path Capture jpg Encoding By
  • 将原始查询转换为 Laravel eloquent

    如何将此原始查询转换为 Laravel 雄辩的方式 select c name as country from country c address ad city ci where ad id 1 and city id ad city i
  • 使用 Three.js 加载 .obj 时出现问题

    我正在尝试使用 Three js 加载 obj 文件 但不幸的是 它说错误 无法加载资源 服务器响应状态为 404 未找到 下面是我正在使用的示例链接 查看源代码 http mrdoob github io Three js example
  • Spring @RequestParam Map 在 POST 方法中不起作用

    我从 Spring 文档中获取了以下内容 公共 interfaceRequestParam 指示方法参数应绑定到 Web 请求参数的注释 支持 Servlet 和 Portlet 环境中的带注释的处理程序方法 如果方法参数是 Map 或 M
  • 为什么删除的内存无法重用

    我在带有 MSVC 9 0 的 Windows 7 上使用 C 并且还能够在带有 MSVC 9 0 的 Windows XP SP3 上进行测试和重现 如果我分配 1 GB 0 5 MB 大小的对象 当我删除它们时 一切正常并且行为符合预期