1967 } |
1967 } |
1968 } |
1968 } |
1969 } |
1969 } |
1970 |
1970 |
1971 // dump the heap to given path. |
1971 // dump the heap to given path. |
1972 int HeapDumper::dump(const char* path) { |
1972 int HeapDumper::dump(const char* path, outputStream* out) { |
1973 assert(path != NULL && strlen(path) > 0, "path missing"); |
1973 assert(path != NULL && strlen(path) > 0, "path missing"); |
1974 |
1974 |
1975 // print message in interactive case |
1975 // print message in interactive case |
1976 if (print_to_tty()) { |
1976 if (out != NULL) { |
1977 tty->print_cr("Dumping heap to %s ...", path); |
1977 out->print_cr("Dumping heap to %s ...", path); |
1978 timer()->start(); |
1978 timer()->start(); |
1979 } |
1979 } |
1980 |
1980 |
1981 // create the dump writer. If the file can be opened then bail |
1981 // create the dump writer. If the file can be opened then bail |
1982 DumpWriter writer(path); |
1982 DumpWriter writer(path); |
1983 if (!writer.is_open()) { |
1983 if (!writer.is_open()) { |
1984 set_error(writer.error()); |
1984 set_error(writer.error()); |
1985 if (print_to_tty()) { |
1985 if (out != NULL) { |
1986 tty->print_cr("Unable to create %s: %s", path, |
1986 out->print_cr("Unable to create %s: %s", path, |
1987 (error() != NULL) ? error() : "reason unknown"); |
1987 (error() != NULL) ? error() : "reason unknown"); |
1988 } |
1988 } |
1989 return -1; |
1989 return -1; |
1990 } |
1990 } |
1991 |
1991 |
2001 // close dump file and record any error that the writer may have encountered |
2001 // close dump file and record any error that the writer may have encountered |
2002 writer.close(); |
2002 writer.close(); |
2003 set_error(writer.error()); |
2003 set_error(writer.error()); |
2004 |
2004 |
2005 // print message in interactive case |
2005 // print message in interactive case |
2006 if (print_to_tty()) { |
2006 if (out != NULL) { |
2007 timer()->stop(); |
2007 timer()->stop(); |
2008 if (error() == NULL) { |
2008 if (error() == NULL) { |
2009 tty->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]", |
2009 out->print_cr("Heap dump file created [" JULONG_FORMAT " bytes in %3.3f secs]", |
2010 writer.bytes_written(), timer()->seconds()); |
2010 writer.bytes_written(), timer()->seconds()); |
2011 } else { |
2011 } else { |
2012 tty->print_cr("Dump file is incomplete: %s", writer.error()); |
2012 out->print_cr("Dump file is incomplete: %s", writer.error()); |
2013 } |
2013 } |
2014 } |
2014 } |
2015 |
2015 |
2016 return (writer.error() == NULL) ? 0 : -1; |
2016 return (writer.error() == NULL) ? 0 : -1; |
2017 } |
2017 } |
2135 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq); |
2135 jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq); |
2136 } |
2136 } |
2137 dump_file_seq++; // increment seq number for next time we dump |
2137 dump_file_seq++; // increment seq number for next time we dump |
2138 |
2138 |
2139 HeapDumper dumper(false /* no GC before heap dump */, |
2139 HeapDumper dumper(false /* no GC before heap dump */, |
2140 true /* send to tty */, |
|
2141 oome /* pass along out-of-memory-error flag */); |
2140 oome /* pass along out-of-memory-error flag */); |
2142 dumper.dump(my_path); |
2141 dumper.dump(my_path, tty); |
2143 os::free(my_path); |
2142 os::free(my_path); |
2144 } |
2143 } |