Java Agent for Memory Measurements

Related tags

Profilers jamm
Overview

Overview

Jamm provides MemoryMeter, a Java agent for all Java versions to measure actual object memory use including JVM overhead.

Use

To use MemoryMeter, start the JVM with -javaagent:<path to>/jamm.jar.

You can then use MemoryMeter in your code like this:

MemoryMeter meter = MemoryMeter.builder().build();
meter.measure(object);
meter.measureDeep(object);

See MemoryMeter.Builder for more options.

If you would like to use MemoryMeter in a web application, make sure that you do NOT put this jar in WEB-INF/lib, as that may cause problems since your code is accessing a MemoryMeter from a different class loader than the one loaded by the -javaagent and won't see it as initialized.

If you want MemoryMeter not to measure some specific classes, you can mark the classes (or interfaces) using the @Unmetered annotation.

It is good to reuse existing MemoryMeter instances. Creating new MemoryMeter instances can and will cause significant performance penalties and also unnecessary side effects, since all guess-modes rely on java.lang.ClassValue.

Dependency coordinates for the latest version of Jamm

Gradle:

dependencies {
    implementation("com.github.jbellis:jamm:0.4.0")
}

Maven:

<dependency>
    <groupId>com.github.jbellis</groupId>
    <artifactId>jamm</artifactId>
    <version>0.4.0</version>
</dependency>

Building

Build + test:

./gradlew jar test

To run the microbenchmark:

./gradlew microbench
build/microbench <JMH options...>

Public to local Maven repo (in case you need that)

./gradlew publishToMavenLocal

IDEs

You can just open the project in IntelliJ. If you've opened the Maven-ish branch(es) in IntelliJ before, you'll have to remove the .idea folder.

Benchmarks

See Microbench.java

To run the microbenchmarks, execute ./gradlew microbench and run build/microbench from the command line.

Some microbenchmark results (JVM options: -Xms16g -Xmx16g -XX:+UseG1GC -XX:+AlwaysPreTouch):

Java 11.0.8

Benchmark                                 (guess)  (nested)  (refs)  Mode  Cnt   Score   Error  Units
Microbench.arrayByteArray             ALWAYS_SPEC       100       4  avgt    3   0.012 ± 0.019  us/op
Microbench.arrayByteArray           ALWAYS_UNSAFE       100       4  avgt    3   0.012 ± 0.019  us/op
Microbench.arrayByteArray  ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.012 ± 0.017  us/op
Microbench.cls1                       ALWAYS_SPEC       100       4  avgt    3   0.026 ± 0.004  us/op
Microbench.cls1                     ALWAYS_UNSAFE       100       4  avgt    3   0.026 ± 0.005  us/op
Microbench.cls1            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.026 ± 0.004  us/op
Microbench.cls2                       ALWAYS_SPEC       100       4  avgt    3   0.350 ± 0.155  us/op
Microbench.cls2                     ALWAYS_UNSAFE       100       4  avgt    3   0.387 ± 0.030  us/op
Microbench.cls2            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.355 ± 0.040  us/op
Microbench.cls3                       ALWAYS_SPEC       100       4  avgt    3   0.761 ± 0.087  us/op
Microbench.cls3                     ALWAYS_UNSAFE       100       4  avgt    3   0.733 ± 0.130  us/op
Microbench.cls3            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.738 ± 0.099  us/op
Microbench.deeplyNested               ALWAYS_SPEC       100       4  avgt    3  49.825 ± 1.482  us/op
Microbench.deeplyNested             ALWAYS_UNSAFE       100       4  avgt    3  46.260 ± 4.466  us/op
Microbench.deeplyNested    ALWAYS_INSTRUMENTATION       100       4  avgt    3  52.301 ± 8.285  us/op
Microbench.justByteArray              ALWAYS_SPEC       100       4  avgt    3   0.014 ± 0.005  us/op
Microbench.justByteArray            ALWAYS_UNSAFE       100       4  avgt    3   0.014 ± 0.004  us/op
Microbench.justByteArray   ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.014 ± 0.006  us/op
Microbench.justByteBuffer             ALWAYS_SPEC       100       4  avgt    3   0.056 ± 0.011  us/op
Microbench.justByteBuffer           ALWAYS_UNSAFE       100       4  avgt    3   0.058 ± 0.018  us/op
Microbench.justByteBuffer  ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.058 ± 0.029  us/op
Microbench.justString                 ALWAYS_SPEC       100       4  avgt    3   0.059 ± 0.061  us/op
Microbench.justString               ALWAYS_UNSAFE       100       4  avgt    3   0.057 ± 0.019  us/op
Microbench.justString      ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.056 ± 0.001  us/op

Java 8u265

Benchmark                                 (guess)  (nested)  (refs)  Mode  Cnt   Score    Error  Units
Microbench.arrayByteArray             ALWAYS_SPEC       100       4  avgt    3   0.011 ±  0.007  us/op
Microbench.arrayByteArray           ALWAYS_UNSAFE       100       4  avgt    3   0.011 ±  0.006  us/op
Microbench.arrayByteArray  ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.011 ±  0.007  us/op
Microbench.cls1                       ALWAYS_SPEC       100       4  avgt    3   0.023 ±  0.009  us/op
Microbench.cls1                     ALWAYS_UNSAFE       100       4  avgt    3   0.025 ±  0.039  us/op
Microbench.cls1            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.024 ±  0.012  us/op
Microbench.cls2                       ALWAYS_SPEC       100       4  avgt    3   0.357 ±  0.034  us/op
Microbench.cls2                     ALWAYS_UNSAFE       100       4  avgt    3   0.365 ±  0.008  us/op
Microbench.cls2            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.366 ±  0.100  us/op
Microbench.cls3                       ALWAYS_SPEC       100       4  avgt    3   0.773 ±  0.178  us/op
Microbench.cls3                     ALWAYS_UNSAFE       100       4  avgt    3   0.754 ±  0.328  us/op
Microbench.cls3            ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.755 ±  0.396  us/op
Microbench.deeplyNested               ALWAYS_SPEC       100       4  avgt    3  46.889 ± 18.817  us/op
Microbench.deeplyNested             ALWAYS_UNSAFE       100       4  avgt    3  45.166 ±  9.059  us/op
Microbench.deeplyNested    ALWAYS_INSTRUMENTATION       100       4  avgt    3  48.041 ± 14.777  us/op
Microbench.justByteArray              ALWAYS_SPEC       100       4  avgt    3   0.011 ±  0.008  us/op
Microbench.justByteArray            ALWAYS_UNSAFE       100       4  avgt    3   0.011 ±  0.009  us/op
Microbench.justByteArray   ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.011 ±  0.007  us/op
Microbench.justByteBuffer             ALWAYS_SPEC       100       4  avgt    3   0.053 ±  0.013  us/op
Microbench.justByteBuffer           ALWAYS_UNSAFE       100       4  avgt    3   0.053 ±  0.011  us/op
Microbench.justByteBuffer  ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.053 ±  0.014  us/op
Microbench.justString                 ALWAYS_SPEC       100       4  avgt    3   0.055 ±  0.010  us/op
Microbench.justString               ALWAYS_UNSAFE       100       4  avgt    3   0.054 ±  0.007  us/op
Microbench.justString      ALWAYS_INSTRUMENTATION       100       4  avgt    3   0.054 ±  0.019  us/op

Previous (0.3.x) versions of jamm (w/ 8u265)

Mentioned for comparison reasons! Performance numbers for the recent version above.

Benchmark                        (guess)  (nested)  (refs)  Mode  Cnt    Score    Error  Units
Microbench.cls1              ALWAYS_SPEC       100       4  avgt    3    0.243 ±  0.170  us/op
Microbench.cls1            ALWAYS_UNSAFE       100       4  avgt    3    0.304 ±  0.078  us/op
Microbench.cls1                    NEVER       100       4  avgt    3    0.210 ±  0.126  us/op
Microbench.cls2              ALWAYS_SPEC       100       4  avgt    3    2.924 ±  0.272  us/op
Microbench.cls2            ALWAYS_UNSAFE       100       4  avgt    3    3.086 ±  0.419  us/op
Microbench.cls2                    NEVER       100       4  avgt    3    2.624 ±  0.131  us/op
Microbench.cls3              ALWAYS_SPEC       100       4  avgt    3    5.919 ±  1.433  us/op
Microbench.cls3            ALWAYS_UNSAFE       100       4  avgt    3    6.031 ±  1.632  us/op
Microbench.cls3                    NEVER       100       4  avgt    3    5.329 ±  0.513  us/op
Microbench.deeplyNested      ALWAYS_SPEC       100       4  avgt    3  500.569 ± 27.362  us/op
Microbench.deeplyNested    ALWAYS_UNSAFE       100       4  avgt    3  495.529 ± 66.984  us/op
Microbench.deeplyNested            NEVER       100       4  avgt    3  388.130 ± 83.949  us/op
Microbench.justByteArray     ALWAYS_SPEC       100       4  avgt    3    0.012 ±  0.011  us/op
Microbench.justByteArray   ALWAYS_UNSAFE       100       4  avgt    3    0.013 ±  0.004  us/op
Microbench.justByteArray           NEVER       100       4  avgt    3    0.055 ±  0.010  us/op
Microbench.justByteBuffer    ALWAYS_SPEC       100       4  avgt    3    0.942 ±  0.230  us/op
Microbench.justByteBuffer  ALWAYS_UNSAFE       100       4  avgt    3    0.935 ±  0.154  us/op
Microbench.justByteBuffer          NEVER       100       4  avgt    3    0.689 ±  0.247  us/op
Microbench.justString        ALWAYS_SPEC       100       4  avgt    3    0.616 ±  0.165  us/op
Microbench.justString      ALWAYS_UNSAFE       100       4  avgt    3    0.684 ±  0.636  us/op
Microbench.justString              NEVER       100       4  avgt    3    0.574 ±  0.098  us/op

The fine print

MemoryMeter can use java.lang.instrument.Instrumentation.getObjectSize(), which only claims to provide "approximate" results, but in practice seems to work as expected.

Two more implementations are available as well. One is using sun.misc.Unsafe w/ reflection and one just uses reflection. Both are inaccurate and rely on guesses. It is strongly recommended to not use "unsafe" or "specification" and jamm will emit a warning on stderr:

  • The "Unsafe" implementation performs arithmetics on the "cookies" returned by Unsafe.objectFieldOffset(), althought the Javadoc says: Do not expect to perform any sort of arithmetic on this offset; it is just a cookie which is passed to the unsafe heap memory accessors. The implementation does not always consider Java object layouts in under all circumstances for all JVMs.
  • The "specification" is just a best-effort guess-timate that can easily produce results that are wrong w/ newer JVMs and GCs and/or newer Java features.

0.4.0 notes

  • The method MemoryMeter.countChildren() has been removed, because there is a) no corresponding implementation from JDK-8249196 and b) there was no test coverage at all.
  • The construction of the MemoryMeter instance has been refactored to a proper builder pattern to allow distinct classes for each implementation: Instrumentation, Unsafe, Specification).
  • A bunch of internal optimizations went into the existing guess-modes and performance for these modes has also been significantly improved (about 10x, see microbenchmark results above).
  • Support for @Unmetered for fields has been removed for the future implementation of java.lang.Runtime.deepSizeOf() with Java 16.
Comments
  • Adding a pom to help publish to maven central

    Adding a pom to help publish to maven central

    If you don't want to publish to maven central yourself, I can publish it from my groupId and my github... but it would be better if your code was pushed from your repo as the canonical source

    Also did some rework of the tests to make them more portable.

    opened by stephenc 4
  • Workaround for bug in Shenandoah when getting the memory-pool-usage f…

    Workaround for bug in Shenandoah when getting the memory-pool-usage f…

    …or 'Shenandoah':

    Caused by: java.lang.InternalError: Memory Pool not found at java.management/sun.management.MemoryPoolImpl.getUsage0(Native Method) at java.management/sun.management.MemoryPoolImpl.getUsage(MemoryPoolImpl.java:94) at org.github.jamm.MemoryLayoutSpecification.getEffectiveMemoryLayoutSpecification(MemoryLayoutSpecification.java:207) at org.github.jamm.MemoryLayoutSpecification.(MemoryLayoutSpecification.java:31)

    opened by snazy 3
  • How to understand results?

    How to understand results?

    I use jamm to measure a big hashmap size:

        System.out.println(meter.measure(stats));
        System.out.println(meter.measureDeep(stats));
        System.out.println(meter.countChildren(stats));
    

    The result is

    48
    24165760
    780543
    

    I am surprised that the second value is large than the third one. Could you give some explain or definition?

    opened by hrchu 3
  • Tests fail on Ubuntu 10.10 with 64bit Oracle JDK 1.6.0_24

    Tests fail on Ubuntu 10.10 with 64bit Oracle JDK 1.6.0_24

    > java -version
    java version "1.6.0_24"
    Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
    Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)
    

    Test output:

    build-test:
        [javac] /home/work/tmp/jamm/build.xml:80: warning: 'includeantruntime' was not set, defaulting to     build.sysclasspath=last; set to false for repeatable builds
        [javac] Compiling 1 source file to /home/work/tmp/jamm/build/test/classes
    test:
         [echo] running tests
        [mkdir] Created dir: /home/work/tmp/jamm/build/test/output
        [junit] Testsuite: org.github.jamm.MemoryMeterTest
        [junit] Tests run: 6, Failures: 6, Errors: 0, Time elapsed: 0.284 sec
        [junit] 
        [junit] Testcase: testPrimitives(org.github.jamm.MemoryMeterTest):  FAILED
        [junit] expected:<24> but was:<16>
        [junit] 
        [junit] 
        [junit] Testcase: testByteBuffer(org.github.jamm.MemoryMeterTest):  FAILED
        [junit] expected:<56> but was:<48>
        [junit] 
        [junit] 
        [junit] Testcase: testCycle(org.github.jamm.MemoryMeterTest):   FAILED
        [junit] expected:<32> but was:<24>
        [junit] 
        [junit] 
        [junit] Testcase: testInheritance(org.github.jamm.MemoryMeterTest): FAILED
        [junit] expected:<24> but was:<16>
        [junit] 
        [junit] 
        [junit] Testcase: testCollections(org.github.jamm.MemoryMeterTest): FAILED
        [junit] expected:<144> but was:<80>
        [junit] 
        [junit] 
        [junit] Testcase: testDeep(org.github.jamm.MemoryMeterTest):    FAILED
        [junit] expected:<3200032> but was:<2400024>
        [junit] 
        [junit] 
        [junit] Test org.github.jamm.MemoryMeterTest FAILED
    BUILD FAILED
    /home/work/tmp/jamm/build.xml:107: Some test(s) failed.
    
    opened by tomdz 3
  • Improve performance by 10x

    Improve performance by 10x

    This PR improves jamm's performance to measure an arbitrary object graph by factor 10, proven by a microbenchmark.

    To achieve this, a bunch of changes have been made:

    • Remove unused code and untested code paths
    • Separate jamm configuration and runtime (breaking API change) - i.e. introduce a builder-pattern and distinct implementations for the "specification", "instrumentation" and "unsafe" modes.
    • Bunch of optimizations like
      • a specialized "visited-objects-set" for jamm's measureDeep()
      • specialized/optimal code paths for different jamm-modes (was using a lot of ifs in the hot-paths before)
      • memoizing calculated values (fields of a class like #39, class-inclusion-checks
      • added new modes to measure ByteBuffer for Apache Cassandra (see below)
      • deprecate jamm's "unsafe" + "specification" modes to make people aware that using sun.misc.Unsafe is wrong and "specification" (actually: just guessing) cannot be aware of all current and especially future object layouts provided by JDKs/JVMs
      • specialized sizeOfArray() functions
    • A bunch of MemoryMeter.Guess enum values have been deprecated - new ones ALWAYS_INSTRUMENTATION + BEST introduced
    • With JDK-8249196 in mind, these functionalities have been removed:
      • ability to debug (dump the object graph traversal) - this also affected production performance
      • ability to count the number of objects in a graph - this was untested
      • allow easy integration of a new jamm-mode "runtime" for JEP/JDK-8249196
      • @Unmetered no longer allowed on fields, only on types (classes + interfaces)

    This change works w/ C*. A preliminary draft for the C* changes is in the last commit of this branch

    This work is separated into 4 commits:

    • Rename readme to .md
    • Add microbenchmark (jmh)
    • Switch to Gradle to avoid jmh-dependencies leaking into the published pom and not refactor jamm to a multi-module maven-project
    • Refactoring of jamm to gain a 10x improvement (benchmark results in the readme)

    Obsoletes #40

    @szegedi maybe this is interesting for you?

    opened by snazy 2
  • Support alternative behavior when encountering SoftReferences

    Support alternative behavior when encountering SoftReferences

    It looks like right now SoftReference referents are being counted normally, which results in a total that correctly tracks "what is referred to" but not "what is retained", since a SoftReference by definition does not retain its referent.

    Would it be possible to get an option similar to the existing "ignore outer class reference", but for soft references?

    I haven't done a full check (due to not having any convenient code to run to check it), but a casual skim of the source indicates that the same issue probably affects WeakReferences as well, possibly even PhantomReferences?

    opened by Fentonator 2
  • Do not count size of referenced classes.

    Do not count size of referenced classes.

    In case that instance contains reference to Class, MemoryMeter counts size of whole class to size of instance. Example:

    for A B it says 16B, for C 16736B

    import org.github.jamm.MemoryMeter;

    public class Test {

    public static void main(final String[] args) throws InterruptedException {
        MemoryMeter mm = new MemoryMeter();
        System.out.println(mm.measureDeep(new A()));
        System.out.println(mm.measureDeep(new B()));
        System.out.println(mm.measureDeep(new C()));
    }
    
    static class A {}
    
    static class B {
        Class<B> c;
    }
    
    static class C {
        Class<C> c = C.class;
    }
    

    }

    opened by kamenik 2
  • Ignore ModuleDescriptor.class + Class.class to prevent traversing JVM…

    Ignore ModuleDescriptor.class + Class.class to prevent traversing JVM…

    …/JDK-internal structures that cause 'Unable to make field private final ... accessible' exceptions.

    Those errors/exceptions happen when running mvn clean package (i.e. the unit tests) w/ Java 11.

    opened by snazy 1
  • Memoize reflection

    Memoize reflection

    Memoizes slow reflective operations into ClassValue objects. Most notably, creation of a list of accessible, non-primitive Field objects that need to be traversed in measureDeep and countChildren. It also memoizes MemoryLayoutSpecification.sizeOfInstance[WithUnsafe] as both of those also need to retrieve a list of fields.

    A separate commit bumps the required version of Java to 7, since that's when java.lang.ClassValue was introduced.

    opened by szegedi 1
  • Fix output directory not created for mac tests

    Fix output directory not created for mac tests

    Otherwise, ant test breaks with:

    test-mac:
         [echo] Testing with modified object alignment
        [junit] Testsuite: org.github.jamm.GuessTest
        [junit] Exception in thread "main" Unable to write log file
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter.endTestSuite(XMLJUnitResultFormatter.java:197)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.fireEndTestSuite(JUnitTestRunner.java:853)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:577)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1196)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:1041)
        [junit] Caused by: java.nio.file.NoSuchFileException: /Users/attila/Documents/projects/jamm/target/test/output/TEST-org.github.jamm.GuessTest.xml
        [junit] 	at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86)
        [junit] 	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102)
        [junit] 	at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107)
        [junit] 	at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214)
        [junit] 	at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:434)
        [junit] 	at java.nio.file.Files.newOutputStream(Files.java:216)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.FormatterElement$DelayedFileOutputStream.write(FormatterElement.java:379)
        [junit] 	at java.io.OutputStream.write(OutputStream.java:116)
        [junit] 	at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
        [junit] 	at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
        [junit] 	at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
        [junit] 	at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
        [junit] 	at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
        [junit] 	at java.io.BufferedWriter.flush(BufferedWriter.java:254)
        [junit] 	at org.apache.tools.ant.util.DOMElementWriter.openElement(DOMElementWriter.java:368)
        [junit] 	at org.apache.tools.ant.util.DOMElementWriter.write(DOMElementWriter.java:209)
        [junit] 	at org.apache.tools.ant.util.DOMElementWriter.write(DOMElementWriter.java:222)
        [junit] 	at org.apache.tools.ant.util.DOMElementWriter.write(DOMElementWriter.java:222)
        [junit] 	at org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter.endTestSuite(XMLJUnitResultFormatter.java:195)
        [junit] 	... 4 more
    
    opened by szegedi 1
  • Support limited recursion depth on the debugging tree output

    Support limited recursion depth on the debugging tree output

    Would be very nice if there was a way to set the maximum recursion depth of the tree generated by enableDebug(), for cases where it is being used as a "poor man's profiler" when dealing with objects that have a lot of collections or other object containers (and thus can end up having very large trees otherwise).

    opened by Fentonator 1
  • Tests fail with OpenJDK 17 due to an illegal reflective access

    Tests fail with OpenJDK 17 due to an illegal reflective access

    While running tests with OpenJDK 17 a failure occurs due to an illegal reflective access into java.base/java.lang:

      [INFO] -------------------------------------------------------
      [INFO]  T E S T S
      [INFO] -------------------------------------------------------
      [INFO] Running org.github.jamm.MemoryMeterTest
      [ERROR] Tests run: 20, Failures: 1, Errors: 2, Skipped: 5, Time elapsed: 0.147 s <<< FAILURE! - in org.github.jamm.MemoryMeterTest
      [ERROR] testPrimitives(org.github.jamm.MemoryMeterTest)  Time elapsed: 0.005 s  <<< ERROR!
      java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @768debd
              at org.github.jamm.MemoryMeterTest.testPrimitives(MemoryMeterTest.java:443)
      
      [ERROR] testUnmeteredAnnotationOnFields(org.github.jamm.MemoryMeterTest)  Time elapsed: 0.001 s  <<< ERROR!
      java.lang.reflect.InaccessibleObjectException: Unable to make field private final byte[] java.lang.String.value accessible: module java.base does not "opens java.lang" to unnamed module @768debd
              at org.github.jamm.MemoryMeterTest.testUnmeteredAnnotationOnFields(MemoryMeterTest.java:614)
      
      [ERROR] testByteBuffer(org.github.jamm.MemoryMeterTest)  Time elapsed: 0 s  <<< FAILURE!
      java.lang.AssertionError: Shallow empty ByteBuffer expected:<48> but was:<56>
              at org.github.jamm.MemoryMeterTest.testByteBuffer(MemoryMeterTest.java:478)
      
      [INFO] Running org.github.jamm.GuessTest
      Guessed 16, instrumented 24 for {LONG*1}->{FLOAT*1}
      Guessed 16, instrumented 24 for {LONG*1}->{BYTE*4}
      [ERROR] Tests run: 4, Failures: 1, Errors: 0, Skipped: 3, Time elapsed: 0.418 s <<< FAILURE! - in org.github.jamm.GuessTest
      [ERROR] testProblemClasses(org.github.jamm.GuessTest)  Time elapsed: 0.385 s  <<< FAILURE!
      java.lang.AssertionError: Not all guesses matched the instrumented values. See output for details. expected:<0> but was:<2>
              at org.github.jamm.GuessTest.testProblemClasses(GuessTest.java:85)
      
      [INFO]
      [INFO] Results:
      [INFO]
      [ERROR] Failures:
      [ERROR]   GuessTest.testProblemClasses:85 Not all guesses matched the instrumented values. See output for details. expected:<0> but was:<2>
      [ERROR]   MemoryMeterTest.testByteBuffer:478 Shallow empty ByteBuffer expected:<48> but was:<56>
      [ERROR] Errors:
      [ERROR]   MemoryMeterTest.testPrimitives:443 » InaccessibleObject Unable to make field p...
      [ERROR]   MemoryMeterTest.testUnmeteredAnnotationOnFields:614 » InaccessibleObject Unabl...
      [INFO]
      [ERROR] Tests run: 24, Failures: 2, Errors: 2, Skipped: 8
      [INFO]
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD FAILURE
      [INFO] ------------------------------------------------------------------------
    
    opened by merkys 2
  • Illegal reflective access by org.github.jamm.MemoryMeter to field java.util.concurrent.atomic.AtomicReference.value

    Illegal reflective access by org.github.jamm.MemoryMeter to field java.util.concurrent.atomic.AtomicReference.value

    I am using clj-memory-meter and get this:

    WARNING: An illegal reflective access operation has occurred
    WARNING: Illegal reflective access by org.github.jamm.MemoryMeter (file:/tmp/jamm1846689842101955943.jar) to field java.util.concurrent.atomic.AtomicReference.value
    WARNING: Please consider reporting this to the maintainers of org.github.jamm.MemoryMeter
    WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    WARNING: All illegal access operations will be denied in a future release
    

    It sounds rather bad, so I figured it would be best to report it even though I can only guess what it means.

    opened by KaliszAd 0
  • java.lang.reflect.InaccessibleObjectException: Unable to make field jdk.inte rnal.ref.PhantomCleanable

    java.lang.reflect.InaccessibleObjectException: Unable to make field jdk.inte rnal.ref.PhantomCleanable

    The JVM (openjdk 15) sometimes has internal PhantomCleanable those throw an exception

    Jamm must be set as -javaagent: java.lang.RuntimeException: java.lang.reflect.InaccessibleObjectException: Unable to make field jdk.inte
    rnal.ref.PhantomCleanable jdk.internal.ref.PhantomCleanable.prev accessible: module java.base does not "opens jdk.internal.ref" to unnamed module @1ce92674: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.reflect.In
    accessibleObjectException: Unable to make field jdk.internal.ref.PhantomCleanable jdk.internal.ref.PhantomCleanable.prev accessible: module java.base does not "opens jdk.internal.ref" to unnamed module @1ce92674
            at org.github.jamm.MemoryMeterBase.measureDeep(MemoryMeterBase.java:129) [jamm-0.4.0.jar:0.4.0-SNAPSHOT]
    
    
    opened by stephankoelle 3
  • Release 0.3.4?

    Release 0.3.4?

    Hi there, I like this tool. However, I can't include snapshots with my own distributables. There hasn't been a release for 6 years. Would it be possible to create a release from 0.3.4-SNAPSHOT in the near future? Best Regards, Sebastian

    opened by smillies 1
Owner
Jonathan Ellis
Jonathan Ellis
A java agent to generate method mappings to use with the linux `perf` tool

perf-map-agent A java agent to generate /tmp/perf-<pid>.map files for just-in-time(JIT)-compiled methods for use with the Linux perf tools. Build Make

null 1.5k Jan 1, 2023
The Java agent for Apache SkyWalking

Apache SkyWalking Java Agent SkyWalking-Java: The Java Agent for Apache SkyWalking, which provides the native tracing/metrics/logging abilities for Ja

The Apache Software Foundation 447 Jan 5, 2023
Java memory allocation profiler

Aprof - Java Memory Allocation Profiler What is it? The Aprof project is a Java Memory Allocation Profiler with very low performance impact on profile

Devexperts 211 Dec 15, 2022
Tools for tracking down memory / JVM problems & generating predictable-as-possible VM behaviour

Hawkshaw Tools for tracking down memory / JVM problems & generating predictable-as-possible VM behaviour You can Use Hawkshaw to mimic application obj

Martijn Verburg 40 Jan 9, 2021
A memory leak detection library for Android.

LeakCanary ?? A memory leak detection library for Android. square.github.io/leakcanary License Copyright 2015 Square, Inc. Licensed under the Apache

Square 28.1k Jan 3, 2023
One file java script for visualizing JDK flight recorder execution logs as flamegraphs without any dependencies except Java and a browser.

Flamegraph from JFR logs Simple one file Java script to generate flamegraphs from Java flight recordings without installing Perl and the Brendan Gregg

Billy Sjöberg 17 Oct 2, 2022
JVM Explorer is a Java desktop application for browsing loaded class files inside locally running Java Virtual Machines.

JVM Explorer JVM Explorer is a Java desktop application for browsing loaded class files inside locally running Java Virtual Machines. Features Browse

null 109 Nov 30, 2022
Sampling CPU and HEAP profiler for Java featuring AsyncGetCallTrace + perf_events

async-profiler This project is a low overhead sampling profiler for Java that does not suffer from Safepoint bias problem. It features HotSpot-specifi

null 5.8k Jan 3, 2023
BTrace - a safe, dynamic tracing tool for the Java platform

btrace A safe, dynamic tracing tool for the Java platform Version 2.1.0 Quick Summary BTrace is a safe, dynamic tracing tool for the Java platform. BT

btrace.io 5.3k Jan 9, 2023
Fork of tagtraum industries' GCViewer. Tagtraum stopped development in 2008, I aim to improve support for Sun's / Oracle's java 1.6+ garbage collector logs (including G1 collector)

GCViewer 1.36 GCViewer is a little tool that visualizes verbose GC output generated by Sun / Oracle, IBM, HP and BEA Java Virtual Machines. It is free

null 4.1k Jan 4, 2023
Get Method Sampling from Java Flight Recorder Dump and convert to FlameGraph compatible format.

Note: Travis has removed the support for Oracle JDK 8. Therefore the build status is removed temporarily. Converting JFR Method Profiling Samples to F

M. Isuru Tharanga Chrishantha Perera 248 Dec 16, 2022
Tool for creating reports from Java Flight Recorder dumps

jfr-report-tool Tool for creating reports from Java Flight Recorder dumps. Influenced by https://github.com/chrishantha/jfr-flame-graph . Kudos to @ch

Lari Hotari 50 Oct 28, 2022
Log analyser / visualiser for Java HotSpot JIT compiler. Inspect inlining decisions, hot methods, bytecode, and assembly. View results in the JavaFX user interface.

JITWatch Log analyser and visualiser for the HotSpot JIT compiler. Video introduction to JITWatch video Slides from my LJC lightning talk on JITWatch

AdoptOpenJDK 2.8k Jan 3, 2023
Java monitoring for the command-line, profiler included

jvmtop is a lightweight console application to monitor all accessible, running jvms on a machine. In a top-like manner, it displays JVM internal metri

null 1.2k Jan 6, 2023
PerfJ is a wrapper of linux perf for java programs.

PerfJ PerfJ is a wrapper of linux perf for java programs. As Brendan Gregg's words In order to profile java programs, you need a profiler that can sam

Min Zhou 353 Jan 2, 2023
OOM diagnostics for Java.

Polarbear A tool to help diagnose OutOfMemoryError conditions. Polarbear helps track down the root cause of OutOfMemoryError exceptions in Java. When

Cue 20 May 14, 2019
Inline raw ASM instructions in Java

asm-inline At first I thought: Oh, I can make an optimization transformer for Proguard And then this happened. Example: public class Test { public

null 27 Dec 8, 2022
Some utility classes around java records

record-util Some utility classes around java records On the menu MapTrait Transform any record to a java.util.Map just by implementing the interface M

Rémi Forax 32 Apr 6, 2022
Terminal UI JMX (Java management extension) viewer

JMXViewer Terminal UI JMX (Java management extension) viewer Usage java -jar jmxviewer.jar [pid] The PID is optional. If it is not provided, the appli

Ivan Yurchenko 20 Sep 15, 2022