for heapdump=true builds, optionally generate dump on OOM

If the VM runs out of heap space and the "avian.heap.dump" system
property was specified at startup, the VM will write a heap dump to
the filename indicated by that property.  This dump may be analyzed
using e.g. DumpStats.java.
This commit is contained in:
Joel Dice 2010-11-18 10:55:00 -07:00
parent 7b85afedec
commit 19dbc61e9f
4 changed files with 38 additions and 7 deletions

View File

@ -69,6 +69,7 @@ void assert(Context*, bool);
System* system(Context*);
void* tryAllocate(Context* c, unsigned size);
void free(Context* c, const void* p, unsigned size);
void outOfMemory(Context*);
#ifdef USE_ATOMIC_OPERATIONS
inline void
@ -359,7 +360,7 @@ class Segment {
break;
}
} else {
abort(context);
outOfMemory(context);
}
}
}
@ -1708,7 +1709,8 @@ collect(Context* c)
}
}
void* tryAllocate(Context* c, unsigned size)
void*
tryAllocate(Context* c, unsigned size)
{
ACQUIRE(c->lock);
@ -1733,7 +1735,9 @@ void* tryAllocate(Context* c, unsigned size)
return 0;
}
void free(Context* c, const void* p, unsigned size) {
void
free(Context* c, const void* p, unsigned size)
{
ACQUIRE(c->lock);
if (DebugAllocation) {
@ -1755,10 +1759,18 @@ void free(Context* c, const void* p, unsigned size) {
c->count -= size;
}
void free_(Context* c, const void* p, unsigned size) {
void
free_(Context* c, const void* p, unsigned size)
{
free(c, p, size);
}
void
outOfMemory(Context* c)
{
c->client->outOfMemory();
}
class MyHeap: public Heap {
public:
MyHeap(System* system, unsigned limit):
@ -1781,7 +1793,9 @@ class MyHeap: public Heap {
virtual void* allocate(unsigned size) {
void* p = local::tryAllocate(&c, size);
expect(c.system, p);
if (p == 0) {
c.client->outOfMemory();
}
return p;
}

View File

@ -49,6 +49,7 @@ class Heap: public Allocator {
virtual unsigned copiedSizeInWords(void*) = 0;
virtual void copy(void*, void*) = 0;
virtual void walk(void*, Walker*) = 0;
virtual void outOfMemory() = 0;
};
virtual void setClient(Client* client) = 0;

View File

@ -2081,6 +2081,21 @@ class HeapClient: public Heap::Client {
::walk(m->rootThread, w, o, 0);
}
virtual void outOfMemory() {
#ifdef AVIAN_HEAPDUMP
const char* path = findProperty(m->rootThread, "avian.heap.dump");
if (path) {
FILE* out = vm::fopen(path, "wb");
if (out) {
dumpHeap(m->rootThread, out);
fclose(out);
}
}
#endif//AVIAN_HEAPDUMP
abort(m->system);
}
void dispose() {
m->heap->free(this, sizeof(*this));
}

View File

@ -16,8 +16,9 @@ import java.util.Arrays;
* heap dump generated by Avian's heapdump.cpp. The output is a list
* of classes (identified by number in the case of anonymous,
* VM-internal classes), each followed by (1) the total memory
* footprint of all instances of the class, and (2) the number of
* instances. The output is ordered by instance memory footprint.
* footprint of all instances of the class in machine words, and (2)
* the number of instances. The output is ordered by instance memory
* footprint.
*/
public class DumpStats {
private static final int Root = 0;