|
|
|
|
|
|
| Heaps | Allocator | Memory Debuging | RC/GC mechanism |
ACDK contains a flexible Memory Management Framework
Stack object are fast, easy to manage, thread and exception safe.
But for complex frameworks the often doesn't fit very well, references
or Pointer are more flexible (remind: Most problems in programming
can be solved through an additional indirection).
ACDK supports both: Allocation objects on the stack and on the heap.
For allocating objects on the heap, please refer to Stack.
ACDK support an allocation framework with
some predefined Heaps and assoicated Allocators.
- Allocators which supports Garbage Collection with
cyclic references.
- Allocators which supports enumeration of objects.
- Performance of Allocators.
- Fixed size Allocators.
- Reference Counted Allocators or Introspection (Mark/Sweep)
Garbage collectors.
- Threadsafe Allocators.
- Allocators for better scalibity in multiple threads.
- Allocators with sanity check agains out of bounds writing.
The Heap, ACDK should use at default can be specified via a command line option.
Please refer to man acdk_core.
PageAllocator Heap is the default Heap for ACDK.
PageAllocator Heap supports:
Standard reference counting will be used to keep memory footprint small.
On low memory situation the Heap automatically starts the Mark/Sweek Garbage
Collecting to free objects with cyclic reference, which could not be freed by
reference counting.
With the PageAllocator Heap the memory usage of a thread or globally of all threads
can be limited.
The value for the maximum usage of memory can be given by the command line option
-acdk-maxmem [maxmem] (see also man acdk_core) or via the acdk::lang::System.
If the limit is reached, the PageAllocator starts Mark/Sweep Garbage Collecting.
If still not enough memory is available, a OutOfMemoryException will be thrown.
Sample for limit memory usage, and automatic garbage collecting
jlong mmu = System::getMaxMemoryUsage();
jlong cmu = ObjectHeap::curMemUsage();
System::setMaxMemoryUsage(cmu + 1024 * 1024 * 2);
for (int i = 0; i < 1000; ++i)
{
// in the background automatically Mark/Sweek GC will be called
RGcableObject lobj = new GcableObject();
lobj->_other = lobj; // cyclic reference, reference counting gc will not work
}
System::setMaxMemoryUsage(mmu);
System::gc(); // clean garbage
|
Sample for handling out of memory situation
jlong mmu = System::getMaxMemoryUsage();
jlong cmu = ObjectHeap::curMemUsage();
System::setMaxMemoryUsage(cmu + 1024 * 1024 * 2);
try {
RObjectArray holder = new ObjectArray(0);
// run until out of mem
while (true)
{
holder->append(new String("Just a Text"));
}
} catch (ROutOfMemoryException ex) {
}
System::setMaxMemoryUsage(mmu);
|
Following source demonstrates how listing all root objects work:
RInteger rint1 = new Integer(12345678); // is root object
RInteger rint2 = new Integer(8765432);
RObjectArray n = new ObjectArray(1);
n[0] = &rint2; // rint2 is not root, because member of n
// get all root objects
RObjectArray roots = System::getRootObjects();
testAssert(roots->find(&rint1) != -1);
testAssert(roots->find(&rint2) == -1);
for (int i = 0; i < roots->length(); ++i)
{
RObject o = roots[i];
if (instanceof(o, ObjectArray) == true)
{
RObjectArray oa = (RObjectArray)o;
::acdk::lang::System::out->println(
SBSTR("Root Object: (" << Integer::toHexString((int)(void*)o.impl()) << "): "
<< o->getClass()->getName() << ": " << oa->length()));
for (int i = 0; i < oa->length(); ++i)
{
o = oa[i];
if (o != Nil)
::acdk::lang::System::out->println(
SBSTR(" RootArray Object: (" << Integer::toHexString((int)(void*)o.impl()) << "): "
<< o->getClass()->getName() << ": " << o->toString()));
}
}
else
{
::acdk::lang::System::out->println(
SBSTR("Root Object: (" << Integer::toHexString((int)(void*)o.impl()) << "): "
<< o->getClass()->getName() << ": " << o->toString()));
}
}
|
If an memory object will be freed in the PageAllocator Heap, the heap checks if
somebody wrote outside the bounds of the memory object.
A simple Reference Counting Heap.
It doesn't support Mark/Sweep garbage collecting for cyclic objects.
The memory will be allocated directly from the underlying C/C++ heap.
A Heap based on Reference Counting + Garbage Collecting
for cyclic references.
The memory will be allocated directly from the underlying C/C++ heap.
The bookkeeping will of all allocated memory chunks will be done
container.
Garbage Collecting Heap using the Boehm Garbage Collector.
Unfortunatelly the Boehm GC doens't work with ACDK in a stable way.
I will spend for this a little more time.
To integrate the Boehm Garbage Collector you have to do following
steps:
- Download the Boehm Garbage Collector 6.0 or later.
- add the library gc.lib to all ACDK libraries and executable.
- add gc6.0/include path to your Include Path.
- Add the defines to ACDK_HAS_BOEHMGC and ACDK_NO_REFCOUNTING to your
ACDK projects. Alternativally you can edit the ./acdk/Config.h file
and add these defines.
- Copy the gc.dll/gc.so to the ACDKHOME/bin directory.
Other changes in the ACDK sources are not necessary.
But there are some limitations:
- The BGC will not work with other Heaps, because for performance
reasons the Reference Counting will be deactivated when using the BGC.
- Some special Debugging features inspecting the allocated Objects
will not work.
- The WeakReference/WeakHashmap will not work.
- Currently no destructor will work.
|
|