I have a large distributed application with 20,000+ objects. I would like to be able to connect to this running JVM externally and view any arbitrary object and its attributes at any time.
For example, if I have some object instance from the following class
class Temp {
int attribute = 0;
String name = "John";
}
I would like to be able to connect to the JVM and see all instances of this class and its attribute and name values.
I believe this would be possible with a heap dump, but this would be extremely expensive given the application. Also, analyzing such a heap dump is extremely challenging when the size is in the 1GB+ range. Is there some other utility that can provide a triggered snapshot of all objects? Or perhaps a more clever solution to my problem?
I've looked into JConsole and the Java Flight Recorder but these do not provide the features I need. Any other suggestions?
Related
I was analyzing a Java heap dump when one of our application servers ran out of memory. I was using Eclipse Memory Analyzer. It reported the following.
One instance of "akka.dispatch.Dispatcher$$anon$1" loaded by
"sun.misc.Launcher$AppClassLoader # 0xc5602128" occupies 675,632,768
(73.50%) bytes.
What do the $$anon and $1 in the class name mean?
What exactly is the object that's taking 73.5% of heap space? What could be the cause?
First anonymous class. Looking at source code I guess it is the Mailbox: https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Dispatcher.scala#L89 (Scala objects created with traits are compiled to anonymous classes)
The tool you are using should be able to tell which objects are directly hold/referenced by Mailbox and are actually using memory. Probably actors are simply not processing messages fast enough.
i am trying to figure out if there is a 'simple' way to store persistently a large object instance in the JVM memory to be shared and re-used for multiple runs by other programs.
I am working on netbeans using java 8. The data is some ~500 MB of serialized objects. They fit easily in the RAM but take few minutes to de-serialize from disk each time.
Currently the program load a serialized object from the local disk into memory for each run. As the data is only read from during the test, it would be optimal to hold it in memory and access it directly at each run.
We've looked into RMI but the overhead, the marshalling process and the transmission will kill the performance.
I was wondering if there is a more direct way to access data from a program running on the same JVM, like sharing memory.
The multiple runs are to test different processing / parameters on the same input data.
I am open to suggestion on the best practice to achieve this 'pre-loading', any hints would be very appreciated.
Thanks
Java serialization is never going to play well as a persistence mechanism - changes to the classes can easily be incompatible with the previously stored objects meaning they can no longer be de-serialized (and in general all object models evolve one way or another).
While suggestions are is really off-topic on SO, I would advise looking at using a distributed cache such as Hazelcast or Coherence.
While you'll still have to load the objects, both Hazelcast or Coherence provide a scalable way to store objects that can be accessed from other JVMs and provide various ways to handle long-term persistence and evolving classes.
However, neither works well with big object graphs, so you should look at breaking the model apart into key/value pairs.
An example might be an order system where the key might be a composite like this:
public class OrderItemKey
{
private OrderKey orderKey;
private int itemIdex;
...
}
And the value like this:
public class OrderItem
{
private ProductKey productKey;
private int quantity;
...
}
Where OrderItems could be in one cache, while Products would be in another.
Once you've got a model that plays well with a distributed cache you need to look at co-locating related objects (so they're stored in the same JVM) and replicating reference objects.
When you're happy with the model, look at moving processing into the cache nodes where the objects reside rather than pulling them out to perform operation on them. This reduces the network load giving considerable performance gains.
If I understood well you need to read a huge amount of data from disk and use this data only for test purpose.
So every time you run the tests you need to reload them and it slow down your tests.
If this is the situation you can also try to create a disk on memory (ram disk). So your file is saved on a disk with the performances of the ram.
Here is a link for the command ramfs to create it on linux systems
My web application is running in apache tomcat.
The classloader/component org.apache.catalina.loader.WebappClassLoader # 0x7a199fae8 occupies 1,70,86,32,104 (88.08%) bytes.
The memory is accumulated in one instance of java.util.concurrent.ConcurrentHashMap$Segment[] loaded by <system class loader>.
I got this problem while analyzing Heapdump. How to analyze it further ?
You provide very little information so I only can provide very little advice… ;-)
First you need to find out who is using the largest objects (the HashMap in your case). Try to look at the contents of the HashMap so you may find out what it is used for. You should also try to look at where this objects are referenced.
Than you can try to limit its size. Depending on whether it is used by a framework you use or by your own code this can be easy (e.g. configuration change for a frameworks cache), medium (e.g. you need to refactor your own code) or difficult (e.g. it is deeply buried in a library you have no control over).
Often the culprit is not the one you expect: Only because an object instance (in your case the HashMap) accumulates a lot of memory does not mean the "owner" of this object is the root cause of the problem. You might well have to look some levels above or below in the object tree or even in a completely different location. In most cases it is crucial that you know your application very well.
Update: You can try to inspect the contents of a HashMap by right clicking it and selecting Java Collections, Hash Entries. For general objects you can use List objects, with incoming references (to list all objects that reference the selected object) or with outgoing references (to list all object that are referenced by the selected object).
Memory analysis is not an easy task and can require a lot of time, at least if you are not used to it…
If you need further assistance you need to provide more details about your application, the frameworks you use and how the heap looks like in MAT.
This doesn't seem to return any result from Netbeans (which has the same heap analysis tools as VisualVM):
select x.name from java.security.Principal x
The query works if I put the name of a concrete class implementing Principal, but I'd need all implementations.
Tried the same in Eclipse Memory Analyzer, same results.
Any clue?
Heap dump does not have the information which classes implement particular interface. The only information available in the heap dump is about superclass. NetBeans Profiler can overcame this shortcoming - if you take a heap dump, while profiling or monitoring NetBeans project, it can compute the classes implementing particular interface from the project.
JHAT OQL 'instanceof' operator does not work with interface types BUG closed as Won't fix because current heap dump format have no such info. There are:
BT2:WORK AROUND
Manually find all implementing classes available in the heap snapshot (e.g. by searching through JAR
files). Besides the difficulty and unreliability of finding all the possible impl classes, the
result will not be very satisfactory because you are forced to either
Run a separate OQL query for each implementing class, making it hard to see all results in one
place.
or
Use 'from Object o' and filter the results by checking the type, which is likely to be
prohibitively slow since it would traverse every object in the heap.
If you have some guess about class names or packages you may use query like this to find appropriate candidates:
filter(heap.classes(), "/org\\.hibernate\\.cfg\\.naming/(it.name)")
You can save search result via:
x = toArray(filter(..., ...))
and then query detail info without waiting for original query:
map(x, "{cl: it, sub: it.subclasses(), sup: it.superclasses()}")
I would like to get a reference to all objects in the Java heap, even if I don't immediately have a reference to those objects in my active thread. I don't need non-referenced objects (those "queued" for garbage collection), but would like to get anything that's still in use.
The goal is to serialize and store all the objects to implement a poor-man's persistence of execution state. I realize that the rabbit hole goes deep when it comes to different types of transient state, but simply persisting objects & loaded class definitions would be useful to me.
Is there a way to access the heap in order to make this happen? Am I overlooking a more straightfoward approach?
I'd look into the the instrument package. Instrument the classes you are interested in so the ctor registers the created instance. You might be able to do this via AspectJ should you not want to use the java.lang.instrument or if the objects are created via something you can control (an IoC container or factories) then you can do something a good chunk less magical.
If you want to take a heap dump programmatically, you'll not find suitable APIs in the java.* or javax.* namespace. However, the Sun runtime comes with the HotSpotDiagnosticMXBean which will enable you to take a heap dump by writing the contents of the heap on to a specified file in disk.
I suggest you take a heap dump and then inspect it using the Eclipse Memory Analyser.
The views available allow you to drill down to instance level, view object properties. You can even query objects using OQL - and SQL-like query language for objects.
The left panel in the below screenshot demonstrates inspecting field values.
screenshot http://img181.imageshack.us/img181/4013/dominatortreegrouped.png