问题标签 [memory-fragmentation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
847 浏览

c - 编写我自己的内存管理器

我想分配一些巨大的动态内存,然后为它编写我自己的内存管理器。即当我的代码需要内存时,我会从这个内存池中分配。我希望算法能够处理内部和外部碎片。哪个是最有效的算法?

0 投票
3 回答
3304 浏览

c++ - 是什么在 Windows Server 2003 上使用了这么多未提交的“私有数据”?

所以我有一个本机 C++ 应用程序,它需要长时间跟踪很多事情。当任务管理器说进程达到 800 到 1200 MB 内存之间的某个位置时,它的内存不足,而限制应该是大约 2GB。

当我对我的进程运行 VMMap 时,我终于知道发生了什么,但这只是给了我更多的问题。我发现了什么:

  • 总大小(类型:总计,列:大小)比任务管理器/进程资源管理器报告的要大得多
  • 在我的程序内存不足之前,总大小似乎实际上是不能超过 2GB 的值
  • 内存使用差异几乎完全是由“私人数据”引起的——“大小”比“承诺”多得多。我见过大约 800MB 已提交的私有数据,但“大小”约为 1700MB。
  • “私有数据”的最大块主要由一对具有“读/写”保护并完全提交的小子块(通常在 4K 和 16K 之间)和一个较大的子块(介于90K 和 400K)具有“保留”保护且未提交。这似乎是对资源的巨大浪费。并且通常在末尾有一个大的(数兆字节)子块是“保留的”并且未提交。
  • 这对中的一小部分通常有我认识的字符串,而较大的部分根本没有字符串。

这些子块对的一个例子:(不是我的应用程序,但想法是一样的) http://www.flickr.com/photos/95123032@N00/5280550393

似乎当一个私有数据块被完全提交时,一个新块(通常与前一个最大块的大小相同或两倍)被分配。听起来很公平。但是,我看到了 3 个块,每个块都超过 100MB,提交的块不到 30MB。我的应用程序不应该以这种可能的方式运行(即用完 400MB,然后在几个小时内缩小 300MB)。

据我所知,“大小”是已分配的虚拟内存地址空间的实际数量。“已提交”是实际使用的“大小”数量(即通过调用 new/malloc)。如果确实如此,那为什么 Size 和 Commited 之间会有如此巨大的差异呢?为什么要分配数百兆字节的块?

有点奇怪的是,在 Windows 7 上运行时的行为完全不同。而在 2003 Server 上,应用程序使用私有数据,而在 Windows 7 上,应用程序使用堆。所以为什么?为什么 VMMap 在 2003 上主要显示私有数据使用情况,而在 7 上主要显示堆使用情况?有什么不同?一个区别是我不能使用 VMMap 中的“堆分配...”按钮来查看所有私有数据的分配位置。

我开始怀疑是否过度使用 std::string 导致了这个问题,因为我在成对中识别的字符串(如上所述)主要由存储在 std::string 中的字符串组成,这些字符串经常被创建和销毁(暗示很多内存分配/释放)。我将所有可能的转换为使用字符数组或使用内存池中的内存,但这似乎没有效果。我所有其他经常新建/删除的对象都已经拥有自己的内存池。

我还发现了低碎片堆,所以我尝试启用它,但它也没有任何区别。我认为这是因为 Windows 2003 实际上并没有正确使用堆。VMMap 显示启用了低碎片堆,但由于它实际上并没有被使用(即它使用的是私有数据),它实际上并没有什么不同。

实际上似乎正在发生的是,这些子块对正在分割大型私有数据块,这导致操作系统分配新块。最终,碎片变得如此糟糕,以至于即使有很多未提交的空间,但似乎没有一个可用,并且进程内存不足。

所以我的问题是:

  1. 为什么 Windows Server 2003 使用私有数据而不是堆?有关系吗?有没有办法让 Windows Server 2003 改用堆内存?如果是这样,那会改善我的情况吗?
  2. 有什么方法可以控制操作系统的内存分配器如何分配私有数据?
  3. 是否可以创建我自己的自定义堆并从中分配(不改变我的大部分代码库),这能改善我的情况吗?我知道可以制作自定义堆,但据我所知,您需要从自定义堆中显式分配,而不是仅仅调用 new 或仅正常使用 STL 容器。
  4. 我有什么遗漏或值得尝试的吗?
0 投票
1 回答
341 浏览

c++ - C++ 分配的奇怪减速

有人可以告诉我为什么会发生以下事情:

我有两台电脑:

  1. 我的工作补偿
  2. 服务器

我维护的 C++ 程序(msvc 2005 c++ 编译)仅在服务器上运行太慢,但在我的计算机上却没有。

我进行了测量(GetThreadTimes 等),可以肯定地说狭窄的地方 - 它的内存分配(new/malloc)。它只发生在服务器上!

我可以声称它是由于内存碎片造成的,因为程序的第一次服务器实例工作正常,只有在数据重新加载到内存(1-150 万分配/释放)之后,它才开始在分配上失去时间。

如果由于两台计算机(我的计算机和服务器)上的内存碎片而看到相同的行为,我不会感到如此惊讶,但我看到的是:1)。在我的补偿分配上花费约 5% 的时间(不准确,但类似)2)。在服务器上,这些分配需要大约 75% 的时间

这怎么可能发生?什么可能会减慢服务器计算机上的 C++ 分配,同时对我的工作站来说还可以。哪里可能有区别?可能它与操作系统级内存管理功能有关?因为 C++ 级别管理器在这两种情况下都是一样的。

这是两种配置:

1)。我的电脑(allocs 占用约 5%):

2)。服务器(allocs 占 ~75%):

将不胜感激澄清这个问题。

0 投票
3 回答
2814 浏览

c++ - 避免内存碎片的方法

我从 RTOS 分配了一个大内存池(我已经知道我的应用程序内存需求,它不会超过一定大小)。然后我的应用程序分配请求从该池中得到满足。

最近我开始面临一个问题;即使内存在那里,分配请求也没有得到满足(有集成的内存基准标记框架,这表明了这一点),调查显示我们正遭受内存碎片的困扰。

我的应用程序严重依赖 STL(也从网络接收数据、XML 解析、图像处理、将其保存为 PNG 等),以及作为内存碎片背后的堆内存分配(还有其他原因吗?),有什么最好的方法来避免它?

0 投票
2 回答
623 浏览

c++ - 允许在短期范围内分配堆对象以确保内存碎片的自由度

我们在嵌入式系统环境中使用 C++,基本上不想要任何类型的动态内存分配(例如,请参阅嵌入式应用程序中的内存管理资源,了解我们不这样做的原因)。我们仍然不想缺少一些不错的基于 C++ 的特性,例如 STL 容器和 std::string。对于第一个,我们会在初始化时保留一个特定的大小,并且不会让容器超出其容量。对于后者(std::string),我对如何“安全”地使用它们有点怀疑,因为它们有时会在堆上分配内存。

不过,我发现使用 std::string (以及通常其他堆分配对象)似乎很好的情况:我会在堆栈上分配对象本身(在{}我正在谈论的某个范围内来自 C++)并允许它们分配堆,前提是它们在超出范围时实际上释放了所有保留的内存。

我知道这种方法并不能绝对保证内存碎片的自由,但我觉得如果手头的范围是短暂的,这实际上会在范围结束后导致连续的可用内存。

我还怀疑,当多个任务共享同一个堆但如果手头的范围都是短暂的(例如,不要阻塞),空闲内存最终应该是连续的,这可能会出现问题。或者,我可以接受的是,只允许一个任务在堆上分配内存,如果这真的很重要,其他任务则不能。

我建议的堆分配对象用法是否有效?是否有人有另一种策略来(部分)启用动态内存分配而不会冒内存碎片的风险?

0 投票
1 回答
3836 浏览

.net - System.Threading.OverlappedData 造成大量内存碎片(异步等待)

我一直在慢慢地耗尽内存。我使用 WinDbg 查看了内存转储,它看起来像这样:

请注意,碎片堆中有更多项目,我只粘贴了超过 10MB 的项目。您可以看出主要问题是 System.Threading.OverlappedData。

最近我重构了所有代码以使用 async & await 到这样的东西:

有很多套接字入站(socket)和出站(azure service bus)通信。如何避免这样的内存碎片?

0 投票
1 回答
93 浏览

.net - 如何为线程管理内存?

我知道 .net 线程的重量很重,每个都消耗约 1MB 的内存(主要用于堆栈)。现在,如果这是一个用户 .net 类,我知道它可能会将大部分内存放入 LOH。但是,由于它是一个核心类,我想知道它的行为是什么。

这个问题的原因是因为我目前正在对一个(可能长期存在的)应用程序进行内存分析,并且似乎存在缓慢的泄漏。我注意到 VS 显示了 33 个线程(处于各种状态,包括已停止)。我想知道线程的节俭使用是否会导致内存碎片化(以及一些 LOH DTO)。

0 投票
1 回答
4772 浏览

.net - .NET 应用程序内存使用率 - 高未使用的 .NET 和非托管内存和碎片

我正在使用 ANTS 内存分析器来诊断我在我的一个 .NET 2.0 应用程序中面临的内存泄漏增加。我在 7.5 小时内拍摄了该过程的 7 个快照,这是所获得数据的表格表示 -

在此处输入图像描述

G1 代表第 1 代大小和 G2 第 2 代大小。除非托管空间和私有字节外,所有其他值均以 MB 为单位。

我的问题是——

  1. 为什么即使堆大小很小,未使用的 .NET 空间也会如此之高?

  2. 我的大型对象堆最多达到 2 MB,在最后 3 个快照期间保持在 96 KB。那为什么会有这么高的大碎片,它们是造成高未使用空间的原因吗?

  3. 非托管空间不断增加。这是否会导致私有字节随着时间的推移而增加?

我无能为力解决这个问题,并进行了多次分析,但找不到合适的解决方案。我准备提供所需的任何其他数据。

0 投票
1 回答
1078 浏览

c++ - 内存泄漏还是内存碎片?

我在Borland Builder C++ 6中运行以下代码,可以看到内存(私有工作集)、Windows 任务管理器中程序使用的内存增加,我认为这是内存泄漏。

我尝试用 Builder C++ 替换默认内存管理器,FASTMM4但看到相同的行为。是因为内存泄漏还是内存碎片,因为我在两者之间感到困惑。我相信在这两种情况下,程序都必须将虚拟内存分页到磁盘,从而增加使用的内存。

查看虚拟内存是区分泄漏和碎片的好主意,但我该怎么做呢?windows 里面有没有工具可以测试呢?

0 投票
1 回答
285 浏览

memory-leaks - 区分内存泄漏和内存碎片

我使用 linux 命令top观察正在运行的程序,我可以看到该程序使用的内存在增加。

如何判断该症状是由内存泄漏或内存碎片引起的?