Out of virtual memory address space (Borland C++ Builder 6 program)

我与影子孤独终老i 提交于 2019-12-14 01:39:49

问题


I have problem with some application written under C++ Builder 6. After some time of running (week, month) the application crashes and closes without any error message. In my application log shortly before crash i get many "Out of memory" exceptions. I looked at the process when it was throwing out of memory exceptions (screenshot below) and it has lots of uncommitted private memory space. What can be a reason of such behavior?

I had such problem once, couple years ago. The reason for that was an option "use dynamic libraries" unchecked in linker options. When I checked it back the problem disappeared and vice versa. The test application which I made was just calling "new char[1000000]" and then delete. The memory was freed every time (no committed memory rise in windows task manager), but after some time I got out of memory, VMMap showed exactly the same thing. Lots of reserved private memory but most of it uncommitted.

Now the problem returned but I can't fix it the same way. I don't know if that was the reason but I had Builder 6 and 2010 istalled on the same machine. Now I just have Builder 6 and it seems that I cannot reproduce the error with test application like before. Ether way it seems that there is some memory manager error or something. CodeGuard doesn't show any memory leaks. When I create memory block with "new" it instantly shows in "memory commit size" and when delete the memory usage decreases, so I assume that the memory leaks are not the case, task manager doesn't show much "memory commit size".

Is there anything I can do? Is there any way I can release uncommitted memory? How to diagnose the problem any further?

The screenshot: http://i.stack.imgur.com/UKuTZ.jpg


回答1:


I found a way to simulate this problem and solution.

for(int i=0; i<100; i++)
{
    char * b = new char[100000000];
    new char;
    delete b;
}

Borland memory manager reserves a block of memory which size is multiple of one page which is 4kB. When allocating memory size different than multiple of 4kB there is some free space which borland may use to allocate some other memory chunk. When the first chunk is deallocated the second is still keeping hole memory block reserved.

At first look the code should cause just 100B memory leak, but in fact it will cause memory allocation exception after less than 16 iterations.

I have found two solutions for this problem. One is FastMM, it works but also brings some troubles with it too. Second solution is to exchange borlndmm.dll with the one from Embarcadero Rad Studio 2010. I didn't test it thoroughly yet but it seems to work without any problem.

I should move the hole project to RAD 2010 but for some reasons I got stuck in Borland 6.




回答2:


Prologue

Hmm interesting behaviour... I have to add some thing I learned the hard way. I dismiss BCB6 immediately after try it for few times because it had too much bugs for my taste (in comparison with BCB5 especially with AnsiStrings handling). So I stayed with BCB5 for a long time without any problems. I used it even for a very Big projects like CAD/CAM.

After few years pass I had to move to BDS2006 because of my employer and the problems start (some can be similar to yours). Aside the minor IDE and trace/breakpoint/codeguard bugs there are more important things like:

  1. memory manager

    • 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.

    but I was lucky and solve it here: bds 2006 C hidden memory manager conflicts (class new / delete[] vs. AnsiString)

  2. wrong compile

    Sometimes app is compiled wrongly, no error is thrown but some lines of code are missing in exe and/or are in different order then in source code. I saw this occasionally also in BCB 5,6. To solve that:

    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
  3. beware breakpoint/trace/codeguard behave differently then raw app

    especially with multi-threading App behaves different while traced and while not. Also codeguard do a big difference (and I do not mean the slow down of execution which corrupts sensitive timing). For example codeguard has a nasty habit of throwing out of memory exceptions without a reason sometimes so some parts of code must be checked over and over until it goes through sometimes even if the mem usage is still the same and far from out of mem.

  4. AnsiString operators

    There are two types of AnsiString in VCL normal and component property. So it is wise to take that into account because for component property AnsiString's are the operation of operators different. Try for example something like

    Edit1->Text+="xxx";
    

    also there are still AnsiString operator bugs like this:

    AnsiString version="aaa"+AnsiString("aaa")+"aaa";       // codeguard: array access violation
    
  5. Import older BCB projects

    Avoid direct import if possible it often creates some unknown allocation and memleaks errors. I am not sure why but I suspect that imported window classes are handled differently and the memleaks are related to bullet #1. Better way is create new App and create/copy components and code manually. I know it is backword but the only safe way to avoid problems still don't know where is the problem but simple *.bdsproj replacement will not help !!! And in *.dfm I had not seen anything suspicious.



来源:https://stackoverflow.com/questions/14873599/out-of-virtual-memory-address-space-borland-c-builder-6-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!