首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >虚拟内存地址空间(Borland C++ Builder 6程序)

虚拟内存地址空间(Borland C++ Builder 6程序)
EN

Stack Overflow用户
提问于 2013-02-14 11:18:19
回答 2查看 3.3K关注 0票数 3

我对一些在C++ Builder 6下编写的应用程序有问题。在运行了一段时间(周、月)之后,应用程序崩溃并关闭,没有任何错误消息。在崩溃前不久的应用程序日志中,我得到了许多“内存不足”异常。当它抛出内存异常(下面的屏幕截图)时,我查看了这个过程,它有很多未提交的私有内存空间。这种行为的原因是什么?

几年前我曾经遇到过这样的问题。原因是在链接器选项中没有选中“使用动态库”选项。当我把它查回来时,问题消失了,反之亦然。我创建的测试应用程序只是调用“新char1000000”,然后删除。每次都释放内存( windows任务管理器中未增加提交内存),但过了一段时间后,VMMap显示了完全相同的情况。很多预留的私有内存,但大部分都没有提交。

现在问题又来了,但我不能用同样的方式解决它。我不知道这是不是原因,但我让Builder6和2010在同一台机器上运行。现在我只有Builder 6,而且似乎无法像以前那样用测试应用程序再现错误。以太的方式,似乎有一些内存管理器错误或什么。CodeGuard没有显示任何内存泄漏。当我用"new“创建内存块时,它会立即显示在”内存提交大小“中,而当删除内存使用量减少时,我假设内存泄漏不是这样,任务管理器就不会显示多少”内存提交大小“。

有什么我能做的吗?有什么办法可以释放未提交的内存吗?如何进一步诊断这个问题?

截图:http://i.stack.imgur.com/UKuTZ.jpg

EN

回答 2

Stack Overflow用户

发布于 2013-03-13 11:54:10

我找到了一种方法来模拟这个问题和解决方案。

代码语言:javascript
复制
for(int i=0; i<100; i++)
{
    char * b = new char[100000000];
    new char;
    delete b;
}

Borland内存管理器保留一个内存块,其大小为一个页面的倍数,即4kB。当分配内存大小与4kB的倍数不同时,borland可以使用一些空闲空间来分配其他内存块。当第一个块被解除分配时,第二个仍然保留洞内存块。

乍一看,代码应该只会导致100 B内存泄漏,但实际上,它会在不到16次迭代之后导致内存分配异常。

我为这个问题找到了两种解决方案--。一个是FastMM,它工作的同时也带来了一些麻烦。第二个解决方案是将borlndmm.dll与Embarcadero 2010中的一个进行交换。我还没有对它进行彻底的测试,但它似乎没有任何问题。

我应该移动洞项目到RAD 2010,但由于某些原因,我被困在博兰6。

票数 3
EN

Stack Overflow用户

发布于 2014-03-04 10:05:18

序言

有趣的行为..。我必须补充一些我很难学到的东西。在尝试了几次之后,我立即解雇了BCB6,因为它有太多的bug(与BCB5相比,特别是AnsiString的处理)。因此,我在BCB5工作了很长一段时间,没有任何问题。我甚至把它用于一个非常大的项目,如CAD/CAM

几年过去了,我不得不搬到BDS2006,因为我的雇主和问题开始了(,有些可以类似于您的)。除了次要的IDE和跟踪/断点/代码保护错误之外,还有更重要的事情,如:

  1. 内存管理器

代码语言:javascript
复制
- `delete/delete[]` corrupts memory manager if called twice for the same pointer **without throwing any exception** to notify ...
- **wrong default constructor/destructor** for `struct` compiler bug was the biggest problem I had (in combination with the `delete`)
- wrong or missing member functions in classes can cause multiple `delete` call !!! due t bug either in compiler or in C++ engine.

但我很幸运在这里解决了它:bds 2006 C hidden memory manager conflicts (class new / delete[] vs. AnsiString)

  1. 错误编译 有时应用程序编译错误,没有抛出错误,但在exe和/或与源代码中的顺序不同的代码中缺少了一些代码行。我偶尔也会在BCB 5,6中看到这种情况。为了解决这个问题:

代码语言:javascript
复制
1. delete all temp files like `~,obj,tds,map,exe,...`
2. close IDE and open it again just to be sure (sometimes view of local variables (mostly big arrays) corrupt IDE memory)
3. compile again

  1. 小心断点/跟踪/代码保护的行为与原始应用程序不同 特别是多线程应用程序在跟踪和不跟踪时的行为有所不同。另外,码保护器做了很大的不同(我并不是说执行的速度慢,这会破坏敏感的计时)。例如,代码保护器有一个糟糕的习惯,就是在没有原因的情况下抛出内存异常,因此必须反复检查代码的某些部分,直到它通过,有时即使mem的用法仍然相同,也远离mem。
  2. AnsiString 算子 在VCL正常属性和组件属性中有两种类型的AnsiString。因此,考虑到这一点是明智的,因为对于组件属性,AnsiString的操作与操作符的操作不同。 编辑1->文本+=“xxx”; 还有一些AnsiString操作符错误,如下所示: AnsiString version="aaa"+AnsiString("aaa")+"aaa";//码保护:数组访问冲突
  3. 导入旧的BCB项目 如果可能的话,避免直接导入,它经常会产生一些未知的分配和内存泄漏错误。我不知道为什么,但我怀疑导入的窗口类是以不同的方式处理的,而且内存泄漏与#1项目有关。更好的方法是创建新的应用程序,手动创建/复制组件和代码。我知道这是背诵,但唯一安全的方法,以避免问题,仍然不知道哪里是问题,但简单的*.bdsproj替换将不会有帮助!在*.dfm,我没有看到任何可疑的东西。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14873599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档