mirror of
https://github.com/corda/corda.git
synced 2025-02-01 16:58:27 +00:00
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:
parent
7b85afedec
commit
19dbc61e9f
24
src/heap.cpp
24
src/heap.cpp
@ -69,6 +69,7 @@ void assert(Context*, bool);
|
|||||||
System* system(Context*);
|
System* system(Context*);
|
||||||
void* tryAllocate(Context* c, unsigned size);
|
void* tryAllocate(Context* c, unsigned size);
|
||||||
void free(Context* c, const void* p, unsigned size);
|
void free(Context* c, const void* p, unsigned size);
|
||||||
|
void outOfMemory(Context*);
|
||||||
|
|
||||||
#ifdef USE_ATOMIC_OPERATIONS
|
#ifdef USE_ATOMIC_OPERATIONS
|
||||||
inline void
|
inline void
|
||||||
@ -359,7 +360,7 @@ class Segment {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
ACQUIRE(c->lock);
|
||||||
|
|
||||||
@ -1733,7 +1735,9 @@ void* tryAllocate(Context* c, unsigned size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free(Context* c, const void* p, unsigned size) {
|
void
|
||||||
|
free(Context* c, const void* p, unsigned size)
|
||||||
|
{
|
||||||
ACQUIRE(c->lock);
|
ACQUIRE(c->lock);
|
||||||
|
|
||||||
if (DebugAllocation) {
|
if (DebugAllocation) {
|
||||||
@ -1755,10 +1759,18 @@ void free(Context* c, const void* p, unsigned size) {
|
|||||||
c->count -= 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);
|
free(c, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
outOfMemory(Context* c)
|
||||||
|
{
|
||||||
|
c->client->outOfMemory();
|
||||||
|
}
|
||||||
|
|
||||||
class MyHeap: public Heap {
|
class MyHeap: public Heap {
|
||||||
public:
|
public:
|
||||||
MyHeap(System* system, unsigned limit):
|
MyHeap(System* system, unsigned limit):
|
||||||
@ -1781,7 +1793,9 @@ class MyHeap: public Heap {
|
|||||||
|
|
||||||
virtual void* allocate(unsigned size) {
|
virtual void* allocate(unsigned size) {
|
||||||
void* p = local::tryAllocate(&c, size);
|
void* p = local::tryAllocate(&c, size);
|
||||||
expect(c.system, p);
|
if (p == 0) {
|
||||||
|
c.client->outOfMemory();
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class Heap: public Allocator {
|
|||||||
virtual unsigned copiedSizeInWords(void*) = 0;
|
virtual unsigned copiedSizeInWords(void*) = 0;
|
||||||
virtual void copy(void*, void*) = 0;
|
virtual void copy(void*, void*) = 0;
|
||||||
virtual void walk(void*, Walker*) = 0;
|
virtual void walk(void*, Walker*) = 0;
|
||||||
|
virtual void outOfMemory() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual void setClient(Client* client) = 0;
|
virtual void setClient(Client* client) = 0;
|
||||||
|
@ -2081,6 +2081,21 @@ class HeapClient: public Heap::Client {
|
|||||||
::walk(m->rootThread, w, o, 0);
|
::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() {
|
void dispose() {
|
||||||
m->heap->free(this, sizeof(*this));
|
m->heap->free(this, sizeof(*this));
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,9 @@ import java.util.Arrays;
|
|||||||
* heap dump generated by Avian's heapdump.cpp. The output is a list
|
* heap dump generated by Avian's heapdump.cpp. The output is a list
|
||||||
* of classes (identified by number in the case of anonymous,
|
* of classes (identified by number in the case of anonymous,
|
||||||
* VM-internal classes), each followed by (1) the total memory
|
* VM-internal classes), each followed by (1) the total memory
|
||||||
* footprint of all instances of the class, and (2) the number of
|
* footprint of all instances of the class in machine words, and (2)
|
||||||
* instances. The output is ordered by instance memory footprint.
|
* the number of instances. The output is ordered by instance memory
|
||||||
|
* footprint.
|
||||||
*/
|
*/
|
||||||
public class DumpStats {
|
public class DumpStats {
|
||||||
private static final int Root = 0;
|
private static final int Root = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user