Example #1
0
  public Snapshot read() throws IOException {
    currPos = 4; // 4 because of the magic number
    version = readVersionHeader();
    identifierSize = in.readInt();
    snapshot.setIdentifierSize(identifierSize);
    if (version >= VERSION_JDK12BETA4) {
      snapshot.setNewStyleArrayClass(true);
    } else {
      snapshot.setNewStyleArrayClass(false);
    }

    currPos += 4;
    if (identifierSize != 4 && identifierSize != 8) {
      throw new IOException(
          "I'm sorry, but I can't deal with an identifier size of "
              + identifierSize
              + ".  I can only deal with 4 or 8.");
    }
    System.out.println("Dump file created " + (new Date(in.readLong())));
    currPos += 8;

    for (; ; ) {
      int type;
      try {
        type = in.readUnsignedByte();
      } catch (EOFException ignored) {
        break;
      }
      in.readInt(); // Timestamp of this record
      // Length of record: readInt() will return negative value for record
      // length >2GB.  so store 32bit value in long to keep it unsigned.
      long length = in.readInt() & 0xffffffffL;
      if (debugLevel > 0) {
        System.out.println(
            "Read record type " + type + ", length " + length + " at position " + toHex(currPos));
      }
      if (length < 0) {
        throw new IOException(
            "Bad record length of " + length + " at byte " + toHex(currPos + 5) + " of file.");
      }
      currPos += 9 + length;
      switch (type) {
        case HPROF_UTF8:
          {
            long id = readID();
            byte[] chars = new byte[(int) length - identifierSize];
            in.readFully(chars);
            names.put(new Long(id), new String(chars));
            break;
          }
        case HPROF_LOAD_CLASS:
          {
            int serialNo = in.readInt(); // Not used
            long classID = readID();
            int stackTraceSerialNo = in.readInt();
            long classNameID = readID();
            Long classIdI = new Long(classID);
            String nm = getNameFromID(classNameID).replace('/', '.');
            classNameFromObjectID.put(classIdI, nm);
            if (classNameFromSerialNo != null) {
              classNameFromSerialNo.put(new Integer(serialNo), nm);
            }
            break;
          }

        case HPROF_HEAP_DUMP:
          {
            if (dumpsToSkip <= 0) {
              try {
                readHeapDump(length, currPos);
              } catch (EOFException exp) {
                handleEOF(exp, snapshot);
              }
              if (debugLevel > 0) {
                System.out.println("    Finished processing instances in heap dump.");
              }
              return snapshot;
            } else {
              dumpsToSkip--;
              skipBytes(length);
            }
            break;
          }

        case HPROF_HEAP_DUMP_END:
          {
            if (version >= VERSION_JDK6) {
              if (dumpsToSkip <= 0) {
                skipBytes(length); // should be no-op
                return snapshot;
              } else {
                // skip this dump (of the end record for a sequence of dump segments)
                dumpsToSkip--;
              }
            } else {
              // HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
              warn("Ignoring unrecognized record type " + type);
            }
            skipBytes(length); // should be no-op
            break;
          }

        case HPROF_HEAP_DUMP_SEGMENT:
          {
            if (version >= VERSION_JDK6) {
              if (dumpsToSkip <= 0) {
                try {
                  // read the dump segment
                  readHeapDump(length, currPos);
                } catch (EOFException exp) {
                  handleEOF(exp, snapshot);
                }
              } else {
                // all segments comprising the heap dump will be skipped
                skipBytes(length);
              }
            } else {
              // HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
              warn("Ignoring unrecognized record type " + type);
              skipBytes(length);
            }
            break;
          }

        case HPROF_FRAME:
          {
            if (stackFrames == null) {
              skipBytes(length);
            } else {
              long id = readID();
              String methodName = getNameFromID(readID());
              String methodSig = getNameFromID(readID());
              String sourceFile = getNameFromID(readID());
              int classSer = in.readInt();
              String className = classNameFromSerialNo.get(new Integer(classSer));
              int lineNumber = in.readInt();
              if (lineNumber < StackFrame.LINE_NUMBER_NATIVE) {
                warn("Weird stack frame line number:  " + lineNumber);
                lineNumber = StackFrame.LINE_NUMBER_UNKNOWN;
              }
              stackFrames.put(
                  new Long(id),
                  new StackFrame(methodName, methodSig, className, sourceFile, lineNumber));
            }
            break;
          }
        case HPROF_TRACE:
          {
            if (stackTraces == null) {
              skipBytes(length);
            } else {
              int serialNo = in.readInt();
              int threadSeq = in.readInt(); // Not used
              StackFrame[] frames = new StackFrame[in.readInt()];
              for (int i = 0; i < frames.length; i++) {
                long fid = readID();
                frames[i] = stackFrames.get(new Long(fid));
                if (frames[i] == null) {
                  throw new IOException("Stack frame " + toHex(fid) + " not found");
                }
              }
              stackTraces.put(new Integer(serialNo), new StackTrace(frames));
            }
            break;
          }
        case HPROF_UNLOAD_CLASS:
        case HPROF_ALLOC_SITES:
        case HPROF_START_THREAD:
        case HPROF_END_THREAD:
        case HPROF_HEAP_SUMMARY:
        case HPROF_CPU_SAMPLES:
        case HPROF_CONTROL_SETTINGS:
        case HPROF_LOCKSTATS_WAIT_TIME:
        case HPROF_LOCKSTATS_HOLD_TIME:
          {
            // Ignore these record types
            skipBytes(length);
            break;
          }
        default:
          {
            skipBytes(length);
            warn("Ignoring unrecognized record type " + type);
          }
      }
    }

    return snapshot;
  }