hotspot/src/share/vm/services/heapDumper.cpp
changeset 2141 e9a644aaff87
parent 1893 c82e388e17c5
child 2154 72a9b7284ccf
equal deleted inserted replaced
2124:6222ebfe4292 2141:e9a644aaff87
   345 enum {
   345 enum {
   346   STACK_TRACE_ID = 1,
   346   STACK_TRACE_ID = 1,
   347   INITIAL_CLASS_COUNT = 200
   347   INITIAL_CLASS_COUNT = 200
   348 };
   348 };
   349 
   349 
   350 
       
   351 // Supports I/O operations on a dump file
   350 // Supports I/O operations on a dump file
   352 
   351 
   353 class DumpWriter : public StackObj {
   352 class DumpWriter : public StackObj {
   354  private:
   353  private:
   355   enum {
   354   enum {
  1301 }
  1300 }
  1302 
  1301 
  1303 // The VM operation that performs the heap dump
  1302 // The VM operation that performs the heap dump
  1304 class VM_HeapDumper : public VM_GC_Operation {
  1303 class VM_HeapDumper : public VM_GC_Operation {
  1305  private:
  1304  private:
  1306   DumpWriter* _writer;
  1305   static VM_HeapDumper* _global_dumper;
       
  1306   static DumpWriter*    _global_writer;
       
  1307   DumpWriter*           _local_writer;
  1307   bool _gc_before_heap_dump;
  1308   bool _gc_before_heap_dump;
  1308   bool _is_segmented_dump;
  1309   bool _is_segmented_dump;
  1309   jlong _dump_start;
  1310   jlong _dump_start;
  1310   GrowableArray<Klass*>* _klass_map;
  1311   GrowableArray<Klass*>* _klass_map;
  1311   ThreadStackTrace** _stack_traces;
  1312   ThreadStackTrace** _stack_traces;
  1312   int _num_threads;
  1313   int _num_threads;
  1313 
  1314 
  1314   // accessors
  1315   // accessors and setters
  1315   DumpWriter* writer() const                    { return _writer; }
  1316   static VM_HeapDumper* dumper()         {  assert(_global_dumper != NULL, "Error"); return _global_dumper; }
       
  1317   static DumpWriter* writer()            {  assert(_global_writer != NULL, "Error"); return _global_writer; }
       
  1318   void set_global_dumper() {
       
  1319     assert(_global_dumper == NULL, "Error");
       
  1320     _global_dumper = this;
       
  1321   }
       
  1322   void set_global_writer() {
       
  1323     assert(_global_writer == NULL, "Error");
       
  1324     _global_writer = _local_writer;
       
  1325   }
       
  1326   void clear_global_dumper() { _global_dumper = NULL; }
       
  1327   void clear_global_writer() { _global_writer = NULL; }
       
  1328 
  1316   bool is_segmented_dump() const                { return _is_segmented_dump; }
  1329   bool is_segmented_dump() const                { return _is_segmented_dump; }
  1317   void set_segmented_dump()                     { _is_segmented_dump = true; }
  1330   void set_segmented_dump()                     { _is_segmented_dump = true; }
  1318   jlong dump_start() const                      { return _dump_start; }
  1331   jlong dump_start() const                      { return _dump_start; }
  1319   void set_dump_start(jlong pos);
  1332   void set_dump_start(jlong pos);
  1320 
  1333 
  1355  public:
  1368  public:
  1356   VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) :
  1369   VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) :
  1357     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
  1370     VM_GC_Operation(0 /* total collections,      dummy, ignored */,
  1358                     0 /* total full collections, dummy, ignored */,
  1371                     0 /* total full collections, dummy, ignored */,
  1359                     gc_before_heap_dump) {
  1372                     gc_before_heap_dump) {
  1360     _writer = writer;
  1373     _local_writer = writer;
  1361     _gc_before_heap_dump = gc_before_heap_dump;
  1374     _gc_before_heap_dump = gc_before_heap_dump;
  1362     _is_segmented_dump = false;
  1375     _is_segmented_dump = false;
  1363     _dump_start = (jlong)-1;
  1376     _dump_start = (jlong)-1;
  1364     _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
  1377     _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
  1365     _stack_traces = NULL;
  1378     _stack_traces = NULL;
  1378   VMOp_Type type() const { return VMOp_HeapDumper; }
  1391   VMOp_Type type() const { return VMOp_HeapDumper; }
  1379   // used to mark sub-record boundary
  1392   // used to mark sub-record boundary
  1380   void check_segment_length();
  1393   void check_segment_length();
  1381   void doit();
  1394   void doit();
  1382 };
  1395 };
       
  1396 
       
  1397 VM_HeapDumper* VM_HeapDumper::_global_dumper = NULL;
       
  1398 DumpWriter*    VM_HeapDumper::_global_writer = NULL;
  1383 
  1399 
  1384 bool VM_HeapDumper::skip_operation() const {
  1400 bool VM_HeapDumper::skip_operation() const {
  1385   return false;
  1401   return false;
  1386 }
  1402 }
  1387 
  1403 
  1477 // writes a HPROF_LOAD_CLASS record for the class (and each of its
  1493 // writes a HPROF_LOAD_CLASS record for the class (and each of its
  1478 // array classes)
  1494 // array classes)
  1479 void VM_HeapDumper::do_load_class(klassOop k) {
  1495 void VM_HeapDumper::do_load_class(klassOop k) {
  1480   static u4 class_serial_num = 0;
  1496   static u4 class_serial_num = 0;
  1481 
  1497 
  1482   VM_HeapDumper* dumper = ((VM_HeapDumper*)VMThread::vm_operation());
       
  1483   DumpWriter* writer = dumper->writer();
       
  1484 
       
  1485   // len of HPROF_LOAD_CLASS record
  1498   // len of HPROF_LOAD_CLASS record
  1486   u4 remaining = 2*oopSize + 2*sizeof(u4);
  1499   u4 remaining = 2*oopSize + 2*sizeof(u4);
  1487 
  1500 
  1488   // write a HPROF_LOAD_CLASS for the class and each array class
  1501   // write a HPROF_LOAD_CLASS for the class and each array class
  1489   do {
  1502   do {
  1490     DumperSupport::write_header(writer, HPROF_LOAD_CLASS, remaining);
  1503     DumperSupport::write_header(writer(), HPROF_LOAD_CLASS, remaining);
  1491 
  1504 
  1492     // class serial number is just a number
  1505     // class serial number is just a number
  1493     writer->write_u4(++class_serial_num);
  1506     writer()->write_u4(++class_serial_num);
  1494 
  1507 
  1495     // class ID
  1508     // class ID
  1496     Klass* klass = Klass::cast(k);
  1509     Klass* klass = Klass::cast(k);
  1497     writer->write_classID(klass);
  1510     writer()->write_classID(klass);
  1498 
  1511 
  1499     // add the klassOop and class serial number pair
  1512     // add the klassOop and class serial number pair
  1500     dumper->add_class_serial_number(klass, class_serial_num);
  1513     dumper()->add_class_serial_number(klass, class_serial_num);
  1501 
  1514 
  1502     writer->write_u4(STACK_TRACE_ID);
  1515     writer()->write_u4(STACK_TRACE_ID);
  1503 
  1516 
  1504     // class name ID
  1517     // class name ID
  1505     symbolOop name = klass->name();
  1518     symbolOop name = klass->name();
  1506     writer->write_objectID(name);
  1519     writer()->write_objectID(name);
  1507 
  1520 
  1508     // write a LOAD_CLASS record for the array type (if it exists)
  1521     // write a LOAD_CLASS record for the array type (if it exists)
  1509     k = klass->array_klass_or_null();
  1522     k = klass->array_klass_or_null();
  1510   } while (k != NULL);
  1523   } while (k != NULL);
  1511 }
  1524 }
  1512 
  1525 
  1513 // writes a HPROF_GC_CLASS_DUMP record for the given class
  1526 // writes a HPROF_GC_CLASS_DUMP record for the given class
  1514 void VM_HeapDumper::do_class_dump(klassOop k) {
  1527 void VM_HeapDumper::do_class_dump(klassOop k) {
  1515   VM_HeapDumper* dumper = ((VM_HeapDumper*)VMThread::vm_operation());
  1528   DumperSupport::dump_class_and_array_classes(writer(), k);
  1516   DumpWriter* writer = dumper->writer();
       
  1517   DumperSupport::dump_class_and_array_classes(writer, k);
       
  1518 }
  1529 }
  1519 
  1530 
  1520 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
  1531 // writes a HPROF_GC_CLASS_DUMP records for a given basic type
  1521 // array (and each multi-dimensional array too)
  1532 // array (and each multi-dimensional array too)
  1522 void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) {
  1533 void VM_HeapDumper::do_basic_type_array_class_dump(klassOop k) {
  1523   VM_HeapDumper* dumper = ((VM_HeapDumper*)VMThread::vm_operation());
  1534   DumperSupport::dump_basic_type_array_class(writer(), k);
  1524   DumpWriter* writer = dumper->writer();
       
  1525   DumperSupport::dump_basic_type_array_class(writer, k);
       
  1526 }
  1535 }
  1527 
  1536 
  1528 // Walk the stack of the given thread.
  1537 // Walk the stack of the given thread.
  1529 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
  1538 // Dumps a HPROF_GC_ROOT_JAVA_FRAME record for each local
  1530 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local
  1539 // Dumps a HPROF_GC_ROOT_JNI_LOCAL record for each JNI local
  1656   } else {
  1665   } else {
  1657     // make the heap parsable (no need to retire TLABs)
  1666     // make the heap parsable (no need to retire TLABs)
  1658     ch->ensure_parsability(false);
  1667     ch->ensure_parsability(false);
  1659   }
  1668   }
  1660 
  1669 
       
  1670   // At this point we should be the only dumper active, so
       
  1671   // the following should be safe.
       
  1672   set_global_dumper();
       
  1673   set_global_writer();
       
  1674 
  1661   // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
  1675   // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1
  1662   size_t used = ch->used();
  1676   size_t used = ch->used();
  1663   const char* header;
  1677   const char* header;
  1664   if (used > (size_t)SegmentedHeapDumpThreshold) {
  1678   if (used > (size_t)SegmentedHeapDumpThreshold) {
  1665     set_segmented_dump();
  1679     set_segmented_dump();
  1666     header = "JAVA PROFILE 1.0.2";
  1680     header = "JAVA PROFILE 1.0.2";
  1667   } else {
  1681   } else {
  1668     header = "JAVA PROFILE 1.0.1";
  1682     header = "JAVA PROFILE 1.0.1";
  1669   }
  1683   }
       
  1684 
  1670   // header is few bytes long - no chance to overflow int
  1685   // header is few bytes long - no chance to overflow int
  1671   writer()->write_raw((void*)header, (int)strlen(header));
  1686   writer()->write_raw((void*)header, (int)strlen(header));
  1672   writer()->write_u1(0); // terminator
  1687   writer()->write_u1(0); // terminator
  1673   writer()->write_u4(oopSize);
  1688   writer()->write_u4(oopSize);
  1674   writer()->write_u8(os::javaTimeMillis());
  1689   writer()->write_u8(os::javaTimeMillis());
  1721   SystemDictionary::always_strong_oops_do(&class_dumper);
  1736   SystemDictionary::always_strong_oops_do(&class_dumper);
  1722 
  1737 
  1723   // fixes up the length of the dump record. In the case of a segmented
  1738   // fixes up the length of the dump record. In the case of a segmented
  1724   // heap then the HPROF_HEAP_DUMP_END record is also written.
  1739   // heap then the HPROF_HEAP_DUMP_END record is also written.
  1725   end_of_dump();
  1740   end_of_dump();
       
  1741 
       
  1742   // Now we clear the global variables, so that a future dumper might run.
       
  1743   clear_global_dumper();
       
  1744   clear_global_writer();
  1726 }
  1745 }
  1727 
  1746 
  1728 void VM_HeapDumper::dump_stack_traces() {
  1747 void VM_HeapDumper::dump_stack_traces() {
  1729   // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
  1748   // write a HPROF_TRACE record without any frames to be referenced as object alloc sites
  1730   DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
  1749   DumperSupport::write_header(writer(), HPROF_TRACE, 3*sizeof(u4));
  1788     return -1;
  1807     return -1;
  1789   }
  1808   }
  1790 
  1809 
  1791   // generate the dump
  1810   // generate the dump
  1792   VM_HeapDumper dumper(&writer, _gc_before_heap_dump);
  1811   VM_HeapDumper dumper(&writer, _gc_before_heap_dump);
  1793   VMThread::execute(&dumper);
  1812   if (Thread::current()->is_VM_thread()) {
       
  1813     assert(SafepointSynchronize::is_at_safepoint(), "Expected to be called at a safepoint");
       
  1814     dumper.doit();
       
  1815   } else {
       
  1816     VMThread::execute(&dumper);
       
  1817   }
  1794 
  1818 
  1795   // close dump file and record any error that the writer may have encountered
  1819   // close dump file and record any error that the writer may have encountered
  1796   writer.close();
  1820   writer.close();
  1797   set_error(writer.error());
  1821   set_error(writer.error());
  1798 
  1822 
  1843     _error = os::strdup(error);
  1867     _error = os::strdup(error);
  1844     assert(_error != NULL, "allocation failure");
  1868     assert(_error != NULL, "allocation failure");
  1845   }
  1869   }
  1846 }
  1870 }
  1847 
  1871 
  1848 
  1872 // Called by error reporting by a single Java thread outside of a JVM safepoint,
  1849 // Called by error reporting
  1873 // or by heap dumping by the VM thread during a (GC) safepoint. Thus, these various
       
  1874 // callers are strictly serialized and guaranteed not to interfere below. For more
       
  1875 // general use, however, this method will need modification to prevent
       
  1876 // inteference when updating the static variables base_path and dump_file_seq below.
  1850 void HeapDumper::dump_heap() {
  1877 void HeapDumper::dump_heap() {
  1851   static char path[JVM_MAXPATHLEN];
  1878   static char base_path[JVM_MAXPATHLEN] = {'\0'};
       
  1879   static uint dump_file_seq = 0;
       
  1880   char   my_path[JVM_MAXPATHLEN] = {'\0'};
  1852 
  1881 
  1853   // The dump file defaults to java_pid<pid>.hprof in the current working
  1882   // The dump file defaults to java_pid<pid>.hprof in the current working
  1854   // directory. HeapDumpPath=<file> can be used to specify an alternative
  1883   // directory. HeapDumpPath=<file> can be used to specify an alternative
  1855   // dump file name or a directory where dump file is created.
  1884   // dump file name or a directory where dump file is created.
  1856   bool use_default_filename = true;
  1885   if (dump_file_seq == 0) { // first time in, we initialize base_path
  1857   if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
  1886     bool use_default_filename = true;
  1858     path[0] = '\0'; // HeapDumpPath=<file> not specified
  1887     if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') {
  1859   } else {
  1888       // HeapDumpPath=<file> not specified
  1860     assert(strlen(HeapDumpPath) < sizeof(path), "HeapDumpPath too long");
       
  1861     strcpy(path, HeapDumpPath);
       
  1862     // check if the path is a directory (must exist)
       
  1863     DIR* dir = os::opendir(path);
       
  1864     if (dir == NULL) {
       
  1865       use_default_filename = false;
       
  1866     } else {
  1889     } else {
  1867       // HeapDumpPath specified a directory. We append a file separator
  1890       assert(strlen(HeapDumpPath) < sizeof(base_path), "HeapDumpPath too long");
  1868       // (if needed).
  1891       strcpy(base_path, HeapDumpPath);
  1869       os::closedir(dir);
  1892       // check if the path is a directory (must exist)
  1870       size_t fs_len = strlen(os::file_separator());
  1893       DIR* dir = os::opendir(base_path);
  1871       if (strlen(path) >= fs_len) {
  1894       if (dir == NULL) {
  1872         char* end = path;
  1895         use_default_filename = false;
  1873         end += (strlen(path) - fs_len);
  1896       } else {
  1874         if (strcmp(end, os::file_separator()) != 0) {
  1897         // HeapDumpPath specified a directory. We append a file separator
  1875           assert(strlen(path) + strlen(os::file_separator()) < sizeof(path),
  1898         // (if needed).
  1876             "HeapDumpPath too long");
  1899         os::closedir(dir);
  1877           strcat(path, os::file_separator());
  1900         size_t fs_len = strlen(os::file_separator());
       
  1901         if (strlen(base_path) >= fs_len) {
       
  1902           char* end = base_path;
       
  1903           end += (strlen(base_path) - fs_len);
       
  1904           if (strcmp(end, os::file_separator()) != 0) {
       
  1905             assert(strlen(base_path) + strlen(os::file_separator()) < sizeof(base_path),
       
  1906               "HeapDumpPath too long");
       
  1907             strcat(base_path, os::file_separator());
       
  1908           }
  1878         }
  1909         }
  1879       }
  1910       }
  1880     }
  1911     }
  1881   }
  1912     // If HeapDumpPath wasn't a file name then we append the default name
  1882   // If HeapDumpPath wasn't a file name then we append the default name
  1913     if (use_default_filename) {
  1883   if (use_default_filename) {
  1914       char fn[32];
  1884     char fn[32];
  1915       sprintf(fn, "java_pid%d", os::current_process_id());
  1885     sprintf(fn, "java_pid%d.hprof", os::current_process_id());
  1916       assert(strlen(base_path) + strlen(fn) < sizeof(base_path), "HeapDumpPath too long");
  1886     assert(strlen(path) + strlen(fn) < sizeof(path), "HeapDumpPath too long");
  1917       strcat(base_path, fn);
  1887     strcat(path, fn);
  1918     }
  1888   }
  1919     assert(strlen(base_path) < sizeof(my_path), "Buffer too small");
       
  1920     strcpy(my_path, base_path);
       
  1921   } else {
       
  1922     // Append a sequence number id for dumps following the first
       
  1923     char fn[33];
       
  1924     sprintf(fn, ".%d", dump_file_seq);
       
  1925     assert(strlen(base_path) + strlen(fn) < sizeof(my_path), "HeapDumpPath too long");
       
  1926     strcpy(my_path, base_path);
       
  1927     strcat(my_path, fn);
       
  1928   }
       
  1929   dump_file_seq++;   // increment seq number for next time we dump
       
  1930   assert(strlen(".hprof") + strlen(my_path) < sizeof(my_path), "HeapDumpPath too long");
       
  1931   strcat(my_path, ".hprof");
  1889 
  1932 
  1890   HeapDumper dumper(false /* no GC before heap dump */,
  1933   HeapDumper dumper(false /* no GC before heap dump */,
  1891                     true  /* send to tty */);
  1934                     true  /* send to tty */);
  1892   dumper.dump(path);
  1935   dumper.dump(my_path);
  1893 }
  1936 }