8233790: Forward output from heap dumper to jcmd/jmap
Reviewed-by: stuefe, sspitsyn, cjplummer
This commit is contained in:
parent
c2a05a128d
commit
b2a9673829
@ -237,19 +237,7 @@ jint dump_heap(AttachOperation* op, outputStream* out) {
|
|||||||
// This helps reduces the amount of unreachable objects in the dump
|
// This helps reduces the amount of unreachable objects in the dump
|
||||||
// and makes it easier to browse.
|
// and makes it easier to browse.
|
||||||
HeapDumper dumper(live_objects_only /* request GC */);
|
HeapDumper dumper(live_objects_only /* request GC */);
|
||||||
int res = dumper.dump(op->arg(0));
|
dumper.dump(op->arg(0), out);
|
||||||
if (res == 0) {
|
|
||||||
out->print_cr("Heap dump file created");
|
|
||||||
} else {
|
|
||||||
// heap dump failed
|
|
||||||
ResourceMark rm;
|
|
||||||
char* error = dumper.error_as_C_string();
|
|
||||||
if (error == NULL) {
|
|
||||||
out->print_cr("Dump failed - reason unknown");
|
|
||||||
} else {
|
|
||||||
out->print_cr("%s", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
@ -516,19 +516,7 @@ void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
|
|||||||
// This helps reduces the amount of unreachable objects in the dump
|
// This helps reduces the amount of unreachable objects in the dump
|
||||||
// and makes it easier to browse.
|
// and makes it easier to browse.
|
||||||
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
|
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
|
||||||
int res = dumper.dump(_filename.value());
|
dumper.dump(_filename.value(), output());
|
||||||
if (res == 0) {
|
|
||||||
output()->print_cr("Heap dump file created");
|
|
||||||
} else {
|
|
||||||
// heap dump failed
|
|
||||||
ResourceMark rm;
|
|
||||||
char* error = dumper.error_as_C_string();
|
|
||||||
if (error == NULL) {
|
|
||||||
output()->print_cr("Dump failed - reason unknown");
|
|
||||||
} else {
|
|
||||||
output()->print_cr("%s", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int HeapDumpDCmd::num_arguments() {
|
int HeapDumpDCmd::num_arguments() {
|
||||||
|
@ -1969,12 +1969,12 @@ void VM_HeapDumper::dump_stack_traces() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// dump the heap to given path.
|
// dump the heap to given path.
|
||||||
int HeapDumper::dump(const char* path) {
|
int HeapDumper::dump(const char* path, outputStream* out) {
|
||||||
assert(path != NULL && strlen(path) > 0, "path missing");
|
assert(path != NULL && strlen(path) > 0, "path missing");
|
||||||
|
|
||||||
// print message in interactive case
|
// print message in interactive case
|
||||||
if (print_to_tty()) {
|
if (out != NULL) {
|
||||||
tty->print_cr("Dumping heap to %s ...", path);
|
out->print_cr("Dumping heap to %s ...", path);
|
||||||
timer()->start();
|
timer()->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,8 +1982,8 @@ int HeapDumper::dump(const char* path) {
|
|||||||
DumpWriter writer(path);
|
DumpWriter writer(path);
|
||||||
if (!writer.is_open()) {
|
if (!writer.is_open()) {
|
||||||
set_error(writer.error());
|
set_error(writer.error());
|
||||||
if (print_to_tty()) {
|
if (out != NULL) {
|
||||||
tty->print_cr("Unable to create %s: %s", path,
|
out->print_cr("Unable to create %s: %s", path,
|
||||||
(error() != NULL) ? error() : "reason unknown");
|
(error() != NULL) ? error() : "reason unknown");
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -2003,13 +2003,13 @@ int HeapDumper::dump(const char* path) {
|
|||||||
set_error(writer.error());
|
set_error(writer.error());
|
||||||
|
|
||||||
// print message in interactive case
|
// print message in interactive case
|
||||||
if (print_to_tty()) {
|
if (out != NULL) {
|
||||||
timer()->stop();
|
timer()->stop();
|
||||||
if (error() == NULL) {
|
if (error() == NULL) {
|
||||||
tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
|
out->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]",
|
||||||
writer.bytes_written(), timer()->seconds());
|
writer.bytes_written(), timer()->seconds());
|
||||||
} else {
|
} else {
|
||||||
tty->print_cr("Dump file is incomplete: %s", writer.error());
|
out->print_cr("Dump file is incomplete: %s", writer.error());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2137,8 +2137,7 @@ void HeapDumper::dump_heap(bool oome) {
|
|||||||
dump_file_seq++; // increment seq number for next time we dump
|
dump_file_seq++; // increment seq number for next time we dump
|
||||||
|
|
||||||
HeapDumper dumper(false /* no GC before heap dump */,
|
HeapDumper dumper(false /* no GC before heap dump */,
|
||||||
true /* send to tty */,
|
|
||||||
oome /* pass along out-of-memory-error flag */);
|
oome /* pass along out-of-memory-error flag */);
|
||||||
dumper.dump(my_path);
|
dumper.dump(my_path, tty);
|
||||||
os::free(my_path);
|
os::free(my_path);
|
||||||
}
|
}
|
||||||
|
@ -41,24 +41,22 @@
|
|||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
||||||
|
class outputStream;
|
||||||
|
|
||||||
class HeapDumper : public StackObj {
|
class HeapDumper : public StackObj {
|
||||||
private:
|
private:
|
||||||
char* _error;
|
char* _error;
|
||||||
bool _print_to_tty;
|
|
||||||
bool _gc_before_heap_dump;
|
bool _gc_before_heap_dump;
|
||||||
bool _oome;
|
bool _oome;
|
||||||
elapsedTimer _t;
|
elapsedTimer _t;
|
||||||
|
|
||||||
HeapDumper(bool gc_before_heap_dump, bool print_to_tty, bool oome) :
|
HeapDumper(bool gc_before_heap_dump, bool oome) :
|
||||||
_error(NULL), _print_to_tty(print_to_tty), _gc_before_heap_dump(gc_before_heap_dump), _oome(oome) { }
|
_error(NULL), _gc_before_heap_dump(gc_before_heap_dump), _oome(oome) { }
|
||||||
|
|
||||||
// string representation of error
|
// string representation of error
|
||||||
char* error() const { return _error; }
|
char* error() const { return _error; }
|
||||||
void set_error(char* error);
|
void set_error(char* error);
|
||||||
|
|
||||||
// indicates if progress messages can be sent to tty
|
|
||||||
bool print_to_tty() const { return _print_to_tty; }
|
|
||||||
|
|
||||||
// internal timer.
|
// internal timer.
|
||||||
elapsedTimer* timer() { return &_t; }
|
elapsedTimer* timer() { return &_t; }
|
||||||
|
|
||||||
@ -66,12 +64,13 @@ class HeapDumper : public StackObj {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
HeapDumper(bool gc_before_heap_dump) :
|
HeapDumper(bool gc_before_heap_dump) :
|
||||||
_error(NULL), _print_to_tty(false), _gc_before_heap_dump(gc_before_heap_dump), _oome(false) { }
|
_error(NULL), _gc_before_heap_dump(gc_before_heap_dump), _oome(false) { }
|
||||||
|
|
||||||
~HeapDumper();
|
~HeapDumper();
|
||||||
|
|
||||||
// dumps the heap to the specified file, returns 0 if success.
|
// dumps the heap to the specified file, returns 0 if success.
|
||||||
int dump(const char* path);
|
// additional info is written to out if not NULL.
|
||||||
|
int dump(const char* path, outputStream* out = NULL);
|
||||||
|
|
||||||
// returns error message (resource allocated), or NULL if no error
|
// returns error message (resource allocated), or NULL if no error
|
||||||
char* error_as_C_string() const;
|
char* error_as_C_string() const;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user