aaaaa wrote:
Hi all,
Does anybody know if STLPort or SGI STL standard allocators do memory
pooling for the list, map and set?
I recall that SGI had a web page where they explained that they do some
pooling in their allocators. I do not know about STLPort.
Also I have had a look at the BOOST pool_alloc (to be used as a pooling
allocator for lists), but looking into the code it doesn't seem to ever
release (to the global ::free) the memory that was once allocated.
I can understand that such memory can be re-used if I have another list
of the same object types later in the program, but it seems to me that
such pool_alloc should anyway release blocks which happen to be
completely free (*) otherwise the program will always appear to have the
peak memory allocation to the operating system. Like leaking! Doesn't it
really ever free the blocks, or it's my overlook?
Are you sure that a call to free() will release the memory to your
operating system. As far as I understand the language of the standard, the
only guarantee given for free() is that a deallocated region will be
available to malloc() calls from the same program. (Actually, the C
standard, from which C++ inherits free(), can be read so that the
postcondition of free() actually is that the memory will be available for
subsequent calls to malloc() in which case the memory must not be returned
to the operating system.)
On my system I just used the following code to check the behavior of free.
I conforms the the interpretation of the standard that I outlined: at no
point, memory is returned to the operating system.
#include <list>
#include <iostream>
#include <string>
typedef char page [1024];
typedef page* page_ptr;
int main ( void ) {
std::list< page_ptr > ptr_list;
std::cout << "allocating 300 MB of memory.\n";
for ( unsigned int i = 0; i < 300000; ++i ) {
ptr_list.push_b ack( reinterpret_cas t< page_ptr >( malloc( sizeof( page
) ) ) );
}
{
std:: cout << "allocation done, hit enter for deallocation.";
std::string line;
std::getline( std::cin, line );
std::cout << "\n";
}
while( ! ptr_list.empty( ) ) {
free( ptr_list.back() );
ptr_list.pop_ba ck();
}
{
std:: cout << "deallocati on done, hit.";
std::string line;
std::getline( std::cin, line );
std::cout << "\n";
}
std::cout << "allocating 300 MB of memory again.\n";
for ( unsigned int i = 0; i < 300000; ++i ) {
ptr_list.push_b ack( reinterpret_cas t< page_ptr >( malloc( sizeof( page
) ) ) );
}
{
std:: cout << "allocation done, hit enter for deallocation.";
std::string line;
std::getline( std::cin, line );
std::cout << "\n";
}
while( ! ptr_list.empty( ) ) {
free( ptr_list.back() );
ptr_list.pop_ba ck();
}
{
std:: cout << "hit enter to quit.";
std::string line;
std::getline( std::cin, line );
std::cout << "\n";
}
}
If you really need to return memory to the operating system, you will have
to write your own allocator and use system calls, which are system specific
and considered off topic in this group.
Best
Kai-Uwe Bux