https://github.com/jerolba/jmnemohistosyne
JMnemohistosyne executes programmatically memory histograms of Java process
https://github.com/jerolba/jmnemohistosyne
Last synced: 6 months ago
JSON representation
JMnemohistosyne executes programmatically memory histograms of Java process
- Host: GitHub
- URL: https://github.com/jerolba/jmnemohistosyne
- Owner: jerolba
- License: apache-2.0
- Created: 2019-02-17T19:12:46.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-03-27T17:32:20.000Z (over 7 years ago)
- Last Synced: 2024-04-14T19:09:39.775Z (about 2 years ago)
- Language: Java
- Homepage:
- Size: 81.1 KB
- Stars: 15
- Watchers: 4
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.txt
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
[](https://maven-badges.herokuapp.com/maven-central/com.jerolba/jmnemohistosyne)
[](https://circleci.com/gh/jerolba/jmnemohistosyne)
[](https://bintray.com/jerolba/maven/jmnemohistosyne/_latestVersion)
[](http://www.apache.org/licenses/LICENSE-2.0.html)
[](https://codecov.io/gh/jerolba/jmnemohistosyne/)
# JMnemohistosyne
JMnemohistosyne executes programmatically memory histogram of current process using available system `jcmd` command. Parses its output to get the number of instantiated classes and memory consumption of each class.
JMnemohistosyne uses the `jmd` command with the `GC.class_histogram` flag, that forces the execution of a full garbage collection. Remember that `jcmd` command **is only available in JDK**, not in JRE.
Full garbage collection and memory histogram are expensive operations. It is not recommendable to run JMnemohistosyne in production.
Only live objects are profiled and it inspects all objects in heap, used by your own code or by the JVM.
## Current memory histogram
To get a histogram of all objects in memory you create a Histogramer object and call to the createHistogram() method, which will return a MemoryHistogram:
```java
Histogramer histogramer = new Histogramer();
MemoryHistogram histogram = histogramer.createHistogram();
HistogramEntry arrayList = histogram.get("java.util.ArrayList");
System.out.println(arrayList.getInstances());
System.out.println(arrayList.getSize());
for (HistogramEntry entry : histogram) {
System.out.println(entry);
}
```
`MemoryHistogram` class is an iterable collection of `HistogramEntry` objects containing: class name, number of instances and total size of all instances.
You can also search for a particular class by passing its full name to the get method.
All objects in memory are counted, created directly or indirectly by your code or by the JVM in its internal operations.
## Memory histogram difference in code execution
We can measure the number of living objects instantiated within a section of code using a lambda that contains it:
```java
MemoryHistogram diff = Histogramer.getDiff(() -> {
HashMap map = new HashMap<>();
for (int i = 0; i < 10000; i++) {
map.put(i, "" + i);
}
return map;
});
HistogramEntry nodes = diff.get("java.util.HashMap$Node");
System.out.println(nodes.getInstances());
System.out.println(nodes.getSize());
```
Histogramer will take a snapshot of memory histogram before executing lambda code. After executing your code it creates other histogram and calculates the difference between both histograms.
You can put all the code you want and call all the needed code inside the lambda, but be sure that all the instances that you want to be taken into account are referenced by some object that already existed outside the lambda or are referenced by the object that returns the lambda (that implements Supplier>). Otherwise, by forcing the garbage collection the instances will not appear in the histogram and will be lost in memory, like tears in rain.
## Filtering
`MemoryHistogram` class is an iterable collection of `HistogramEntry` objects which contains: class name, number of instances and size of all instancess.
A `MemoryHistogram` can be filtered using the `filter` method with a varargs of:
- Class name including package: `java.util.HashMap`
- Class name with a final wildcard: `java.util.HashMap*`
- Class object: `HashMap.class`
- Regular expression patter over complete class name: `Pattern.compile(".*List")`
```java
MemoryHistogram filterd = histogram.filter("Object[]", "java.util.HashMap*", ArrayList.class, Pattern.compile(".*Hibernate.*"));
```
All options are applied to the histogram and joined in a new `MemoryHistogram`.
## Dependency
JMnemohistosyne is uploaded to Maven Central Repository and to use it, you need to add the following Maven dependency:
```xml
com.jerolba
jmnemohistosyne
0.2.3
```
in Gralde:
`implementation 'com.jerolba:jmnemohistosyne:0.2.3'`
or download the single [jar](http://central.maven.org/maven2/com/jerolba/jmnemohistosyne/0.2.3/jmnemohistosyne-0.2.3.jar) from Maven Central Repository.
### JDK
JMnemohistosyne depends on the presence of the `jcmd` command in the path. Then, check that the JDK is installed and is accesible from command line.
Currently it is tested in the [CI system](https://circleci.com/gh/jerolba/jmnemohistosyne) against: Oracle JDK 8, OpenJDK 8 and OpendJDK 11.
## Contribute
Feel free to dive in! [Open an issue](https://github.com/jerolba/jmnemohistosyne/issues/new) or submit PRs.
Any contributor and maintainer of this project follows the [Contributor Covenant Code of Conduct](https://github.com/jerolba/jmnemohistosyne/blob/master/CODE_OF_CONDUCT.md).
## License
[Apache 2](https://github.com/jerolba/jmnemohistosyne/blob/master/LICENSE.txt) © Jerónimo López