8267666: Add option to jcmd GC.heap_dump to use existing file
Reviewed-by: rschmelter, clanger
This commit is contained in:
parent
8973867fb9
commit
7cbb67a3f8
@ -2660,9 +2660,7 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
// create binary file, rewriting existing file if required
|
||||
int os::create_binary_file(const char* path, bool rewrite_existing) {
|
||||
int oflags = O_WRONLY | O_CREAT;
|
||||
if (!rewrite_existing) {
|
||||
oflags |= O_EXCL;
|
||||
}
|
||||
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
|
||||
return ::open64(path, oflags, S_IREAD | S_IWRITE);
|
||||
}
|
||||
|
||||
|
@ -2350,9 +2350,7 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
// create binary file, rewriting existing file if required
|
||||
int os::create_binary_file(const char* path, bool rewrite_existing) {
|
||||
int oflags = O_WRONLY | O_CREAT;
|
||||
if (!rewrite_existing) {
|
||||
oflags |= O_EXCL;
|
||||
}
|
||||
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
|
||||
return ::open(path, oflags, S_IREAD | S_IWRITE);
|
||||
}
|
||||
|
||||
|
@ -4963,9 +4963,7 @@ int os::open(const char *path, int oflag, int mode) {
|
||||
// create binary file, rewriting existing file if required
|
||||
int os::create_binary_file(const char* path, bool rewrite_existing) {
|
||||
int oflags = O_WRONLY | O_CREAT;
|
||||
if (!rewrite_existing) {
|
||||
oflags |= O_EXCL;
|
||||
}
|
||||
oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
|
||||
return ::open64(path, oflags, S_IREAD | S_IWRITE);
|
||||
}
|
||||
|
||||
|
@ -4801,9 +4801,7 @@ bool os::dir_is_empty(const char* path) {
|
||||
// create binary file, rewriting existing file if required
|
||||
int os::create_binary_file(const char* path, bool rewrite_existing) {
|
||||
int oflags = _O_CREAT | _O_WRONLY | _O_BINARY;
|
||||
if (!rewrite_existing) {
|
||||
oflags |= _O_EXCL;
|
||||
}
|
||||
oflags |= rewrite_existing ? _O_TRUNC : _O_EXCL;
|
||||
return ::open(path, oflags, _S_IREAD | _S_IWRITE);
|
||||
}
|
||||
|
||||
|
@ -468,10 +468,13 @@ HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
|
||||
"BOOLEAN", false, "false"),
|
||||
_gzip("-gz", "If specified, the heap dump is written in gzipped format "
|
||||
"using the given compression level. 1 (recommended) is the fastest, "
|
||||
"9 the strongest compression.", "INT", false, "1") {
|
||||
"9 the strongest compression.", "INT", false, "1"),
|
||||
_overwrite("-overwrite", "If specified, the dump file will be overwritten if it exists",
|
||||
"BOOLEAN", false, "false") {
|
||||
_dcmdparser.add_dcmd_option(&_all);
|
||||
_dcmdparser.add_dcmd_argument(&_filename);
|
||||
_dcmdparser.add_dcmd_option(&_gzip);
|
||||
_dcmdparser.add_dcmd_option(&_overwrite);
|
||||
}
|
||||
|
||||
void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
|
||||
@ -490,7 +493,7 @@ void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
|
||||
// This helps reduces the amount of unreachable objects in the dump
|
||||
// and makes it easier to browse.
|
||||
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
|
||||
dumper.dump(_filename.value(), output(), (int) level);
|
||||
dumper.dump(_filename.value(), output(), (int) level, _overwrite.value());
|
||||
}
|
||||
|
||||
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
|
||||
|
@ -314,6 +314,7 @@ protected:
|
||||
DCmdArgument<char*> _filename;
|
||||
DCmdArgument<bool> _all;
|
||||
DCmdArgument<jlong> _gzip;
|
||||
DCmdArgument<bool> _overwrite;
|
||||
public:
|
||||
HeapDumpDCmd(outputStream* output, bool heap);
|
||||
static const char* name() {
|
||||
|
@ -1905,7 +1905,7 @@ void VM_HeapDumper::dump_stack_traces() {
|
||||
}
|
||||
|
||||
// dump the heap to given path.
|
||||
int HeapDumper::dump(const char* path, outputStream* out, int compression) {
|
||||
int HeapDumper::dump(const char* path, outputStream* out, int compression, bool overwrite) {
|
||||
assert(path != NULL && strlen(path) > 0, "path missing");
|
||||
|
||||
// print message in interactive case
|
||||
@ -1928,7 +1928,7 @@ int HeapDumper::dump(const char* path, outputStream* out, int compression) {
|
||||
}
|
||||
}
|
||||
|
||||
DumpWriter writer(new (std::nothrow) FileWriter(path), compressor);
|
||||
DumpWriter writer(new (std::nothrow) FileWriter(path, overwrite), compressor);
|
||||
|
||||
if (writer.error() != NULL) {
|
||||
set_error(writer.error());
|
||||
|
@ -71,7 +71,7 @@ class HeapDumper : public StackObj {
|
||||
// dumps the heap to the specified file, returns 0 if success.
|
||||
// additional info is written to out if not NULL.
|
||||
// compression >= 0 creates a gzipped file with the given compression level.
|
||||
int dump(const char* path, outputStream* out = NULL, int compression = -1);
|
||||
int dump(const char* path, outputStream* out = NULL, int compression = -1, bool overwrite = false);
|
||||
|
||||
// returns error message (resource allocated), or NULL if no error
|
||||
char* error_as_C_string() const;
|
||||
|
@ -34,7 +34,7 @@
|
||||
char const* FileWriter::open_writer() {
|
||||
assert(_fd < 0, "Must not already be open");
|
||||
|
||||
_fd = os::create_binary_file(_path, false); // don't replace existing file
|
||||
_fd = os::create_binary_file(_path, _overwrite);
|
||||
|
||||
if (_fd < 0) {
|
||||
return os::strerror(errno);
|
||||
|
@ -61,10 +61,11 @@ public:
|
||||
class FileWriter : public AbstractWriter {
|
||||
private:
|
||||
char const* _path;
|
||||
bool _overwrite;
|
||||
int _fd;
|
||||
|
||||
public:
|
||||
FileWriter(char const* path) : _path(path), _fd(-1) { }
|
||||
FileWriter(char const* path, bool overwrite) : _path(path), _overwrite(overwrite), _fd(-1) { }
|
||||
|
||||
~FileWriter();
|
||||
|
||||
|
@ -50,13 +50,15 @@ import jdk.test.lib.dcmd.PidJcmdExecutor;
|
||||
public class HeapDumpTest {
|
||||
protected String heapDumpArgs = "";
|
||||
|
||||
public void run(CommandExecutor executor) throws IOException {
|
||||
public void run(CommandExecutor executor, boolean overwrite) throws IOException {
|
||||
File dump = new File("jcmd.gc.heap_dump." + System.currentTimeMillis() + ".hprof");
|
||||
if (dump.exists()) {
|
||||
if (!overwrite && dump.exists()) {
|
||||
dump.delete();
|
||||
} else if (overwrite) {
|
||||
dump.createNewFile();
|
||||
}
|
||||
|
||||
String cmd = "GC.heap_dump " + heapDumpArgs + " " + dump.getAbsolutePath();
|
||||
String cmd = "GC.heap_dump " + (overwrite ? "-overwrite " : "") + heapDumpArgs + " " + dump.getAbsolutePath();
|
||||
executor.execute(cmd);
|
||||
|
||||
verifyHeapDump(dump);
|
||||
@ -85,7 +87,12 @@ public class HeapDumpTest {
|
||||
/* GC.heap_dump is not available over JMX, running jcmd pid executor instead */
|
||||
@Test
|
||||
public void pid() throws IOException {
|
||||
run(new PidJcmdExecutor());
|
||||
run(new PidJcmdExecutor(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pidRewrite() throws IOException {
|
||||
run(new PidJcmdExecutor(), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user