Giter Site home page Giter Site logo

mat's Introduction

MAT

What is it?

MAT is a tool to programmatically work with java heap dumps. While there are many tools for analyzing heap dumps, most of them do not have an API to pull out and work with the objects in the heap direclty. MAT lets you do that. See the extended example below.

Build Instructions

mvn clean install

that will publish to your local maven repo, which then you can include in another project using:

    <dependency>
      <groupId>mat</groupId>
      <artifactId>mat-core</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

Brief History

This code was originally pulled directly from https://bitbucket.org/vshor/mat (sorry I converted to git from mercurial and didn't keep the history because, well, I'm lazy). It was actually discovered from https://github.com/square/haha, but that only works for Android heap dumps. vshor/mat was in turn taken from the Eclipse Memory Analyzer Tool (MAT), but that is unusable outside of Eclipse.

Example

My original use case was when I wanted to work with the objects in a heap dump. Though I could browse the objects in YourKit, I couldn't work with them programmatically. In particular, the heap dump I was working with had lots of 80 MB buffers, and I had no idea what was in them. A coworker suggested I look for ascii strings in the buffers to see if that helped shed light on their contents. I could browse bits of the buffer graphically in YourKit -- but I couldn't do a comprehensive search over 80 MB.

But using MAT, I could pull the byte arrays out of the heap dump, and then work with them directly. Here's an example in scala:

  import java.io.File
  import scala.collection.JavaConverters._

  import org.eclipse.mat.util.IProgressListener
  import org.eclipse.mat.parser.internal.SnapshotFactory
  import org.eclipse.mat.util.IProgressListener.Severity
  import org.eclipse.mat.snapshot.model.IPrimitiveArray

  val factory = new SnapshotFactory()
  val path = "..."

  val listener = new IProgressListener {
    override def sendUserMessage(severity: Severity, s: String, throwable: Throwable): Unit = {
      println(s"$severity: $s $throwable")
    }

    override def isCanceled: Boolean = false

    var workedTotal = 0

    override def done(): Unit = {
      println("done")
    }

    override def worked(i: Int): Unit = {
      workedTotal += i
      println(s"worked $i (total = $workedTotal)")
    }

    override def setCanceled(b: Boolean): Unit = {}

    override def subTask(s: String): Unit = {
      println(s"subtask $s")
    }

    override def beginTask(s: String, i: Int): Unit = {
      println(s"Beginning ${s} with $i units")
    }
  }

  val start = System.currentTimeMillis()
  val snapshot = factory.openSnapshot(new File(path), new java.util.HashMap(), listener)
  val end = System.currentTimeMillis()
  println(s"heap loaded in ${(end - start) / 1000}s")


  val clsName = new Array[Byte](0).getClass().getCanonicalName()
  val icls = snapshot.getClassesByName(clsName, false).asScala.head
  val byteArrayIds = icls.getObjectIds
  val bigByteArrayId = byteArrayIds.maxBy{id => snapshot.getHeapSize(id)}

  val bigByteArray = snapshot.getObject(bigByteArrayId).asInstanceOf[IPrimitiveArray]
  val arr = bigByteArray.getValueArray.asInstanceOf[Array[Byte]]


  /**
    * find runs of bytes that might be ascii characters and print them out to see
    * if they might be meaningful strings
    */
  def findStrings(bytes: Array[Byte], minLength: Int = 8): Unit = {
    var idx = 0
    var inPrintable = false
    var printableBegin = -1
    while (idx < bytes.length) {
      val printable = (bytes(idx) >= 32 && bytes(idx) < 127)
      if (printable && !inPrintable) {
        inPrintable = true
        printableBegin = idx
      } else if (!printable && inPrintable) {
        if (idx - printableBegin >= minLength) {
          val str = new String(bytes.slice(printableBegin, idx).map{_.toChar})
          println(s"""printable from ${printableBegin} to ${idx}: "$str"""")
        }
        inPrintable = false
      }
      idx += 1
    }
  }
  
  findStrings(arr)

mat's People

Contributors

squito avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.