注册 登录
编程论坛 C++教室

[讨论]test how big is the heap memory

HJin 发布于 2007-06-22 10:15, 1063 次点击

Following is my simple test. If you have a better test algorithm,
please drop me a line.

Thanks,

HJin


/*---------------------------------------------------------------------------
File name: HeapMemoryTest.cpp
Author: HJin
Created on: 6/21/2007 19:05:18

Modification history:

We want to know how big the heap memory is, when
we use new or malloc to dynamically allocate memory.

My machine has 1Gb physical memory, so the heap memory
is less than 1Gb. My test shows that 3/4 of the physical
memory can be used for the heap.

Sample output:

heap addr = 00385008
heap exhausted
heap addr ends at 2d20d728
approximate heap size is 718.533 M
Inside eat_memory(). heap addr is 00385008
Press any key to continue . . .

*/

#include <iostream>
#include <new>
using namespace std;

const int BlockSize = 1024; // 1k
int *pSave;
long addrKeeper = 0L;
bool hasMoreMemory = true;

void get_memory()
{
cerr << "heap exhausted" << endl;
cout<<"heap addr ends at "<<std::hex<<addrKeeper<<endl;
cout<<"approximate heap size is "<<std::oct<<double(addrKeeper-(long)pSave)/(1024.0*1024.0)<<" M"<<endl;

delete [] pSave; // release saved block
hasMoreMemory = false;
}

void eat_memory(int size)
{
/**
when this allocation fails, the system calls the new_handler.
Once the new_handler returns, hasMoreMemory = false.
*/
int *p = new int[size]; // allocate memory
if (hasMoreMemory)
{
addrKeeper = (long)p;
eat_memory(size); // recursive call
}
else
cerr << "Inside eat_memory(). heap addr is " << p << endl;
}

int main()
{
set_new_handler(get_memory); // specify handler

pSave = new int[BlockSize]; // save one block from heap
cerr << "heap addr = " << pSave << endl;
eat_memory(BlockSize);

return 0;
}

9 回复
#2
aipb20072007-06-22 11:00
要看懂这段代码还真费力!

你能说说你的思路吗?
还有,我机器上不能运行,会出错。


还有,你一直吃内存,但是好象没有释放吧?
#3
HJin2007-06-22 11:40

0. you may need to disable virtual memory for the system first;

1. eat_memory() eats memory (that block of memory is lost) and never releases it. That is the desgin. When you exhaust the available heap memory, any call to new() will fail; once the new() fails, the program will call the global new_handler (in our case, it is get_memory()). In our customized verion of the new handler (c++ has its own built-in/default new handler), we output information.

2. The source code compiles and runs on my windows xp pro (En) / VS 2005 system.

#4
yuyunliuhen2007-06-22 12:55
When I first compiles the programe,it takes about more than 10 seconds to finish,but the second time only takes less than 1 second.and at that flash my computer' cpu reach 99%;then memory released;test many times,a exception comes up,only a time.

Compile environment:DEV C ++
#5
yuyunliuhen2007-06-22 13:02

[QUOTE]1. eat_memory() eats memory (that block of memory is lost) and never releases it.[/QUOTE]
But it is not that condition on my computer ,I don't konw why and I want to make it.

continue...

[此贴子已经被作者于2007-6-22 17:09:06编辑过]

#6
HJin2007-06-22 15:17

1. The following file simulates the process of new() --- if you never overloaded new() before.

2. In my ogrinal post, I saved one block of memory at the beginning of main(), then I released that saved block to the system in get_memory(), so that the get_memory() can get more memory.

After the call to get_memory(), this statement in eat_memory()

int *p = new int[size]; // allocate memory

can run once more (and only 1 time) and then go to the "else" branch.

3. Don't know why it cannot run on your guys' system.


/*---------------------------------------------------------------------------
File name: new_handler.cpp
Author: HJin
Created on: 6/21/2007 23:57:40

Modification history:


Sample output:


my handler here

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Press any key to continue . . .

*/

#include <iostream>
using namespace std;

void myHandler()
{
cout<<"my handler here\n";

terminate(); // or abort()
}

/**
This overload of new() is excerpted from Scott Meyer's
book: Effective C++, which simulates what is going on
for when you say

int * p = new int[size]

in C++.

*/
void* operator new(size_t size) throw (std::bad_alloc)
{
/**
the change for size from 0 to 1 makes any object has
size >=1.

For exmample, if you have an empty class A:

class A
{
};

And you say

A* obj = new A;

Then obj has size >=1.
*/
if(size==0)
size=1;

// infinite loop: the system must make more
// memory available, otherwise it throws a bad_alloc
// exception.
while(1)
{
void *p = 0;
p = malloc(size);
if(p != 0) return p;

// get current new handler
new_handler globalHandler = set_new_handler(0);
// set the new handler
set_new_handler(globalHandler);

// if it is a valid handler, run it.
// In general, the global new handler should make
// more memory availabe from the system.
if(globalHandler)
{
(*globalHandler)();
}
else
{
throw(std::bad_alloc("bad alloc here."));
}
}
}

int main(int argc, char** argv)
{
new_handler oldHandler = set_new_handler(myHandler);

try
{
while(1)
{
int *p = new int[1024];
}
}
// no exception will be caught, since the
// new handler terminates the whole program
catch(const std::bad_alloc& e)
{
cout<<e.what()<<endl;
}
catch(const std::exception& e)
{
cout<<e.what()<<endl;
}

return 0;
}

#7
I喜欢c2007-06-22 18:10


好痛苦的交流
#8
aipb20072007-06-22 20:52
不懂了,呵呵,HJin,还是搞个中文的系统吧,或者装个什么软件可以写汉字!

呵呵~
#9
HJin2007-06-22 23:19
The thing is I am using a corporate laptop --- yes, I am one of the adminstrators; and no, I cannot change the system configuration without the approval from the head of the IT department.
#10
游乐园2007-06-24 20:31
pretty good ...

btw,Mr. HJin,what's your profession now?
It seems that you are full of experience in using C++.Every program u wrote was with adequate explaination and pre-analysis.
Anyhow,plz go on with your post and idea which do benefit us(under graduate students) a lot.
I'd like to catch up with the pace here in my idle online time...
1