Multi-threaded time-based call hierarchy - java

I am using eclipse to write java code. If I'm debugging some code I can set a breakpoint and follow along as the code goes through each of the functions or I can backtrack. I can also look at the call hierarchy or the references to get an idea. But that's not enough.
I would like to have a some sort of time-based visualization of what each thread is doing along the process from ... let's say "point A" (pressing a button on the interface) to "point B" (getting the result). I want to see which classes/methods were called in what order. I want a good way to visualize what kind of output is coming from one method and going into another method which fires off a new process ...etc.
Is a profiler the only thing available for this type of visualization? Basically I want an action diagram or flow diagram created. Is there some plugin or app which can generate something like this?
Edit: Here is an example of what I'm thinking ... at least visually:
essmodel.sourceforge.net/index.html
It has some flow of where the code is leading. But I think this is just a static map of what classes lead to other classes and what inputs/output options are available. I would want to map the flow based on a specific case.

JProfiler offers such a view, it's called the "Call tracer":
It's important to restrict your filters very carefully in order not to record to much data.
Disclaimer: My company develops JProfiler.

I believe using a profiler is going to be your best option. Are you familiar with VisualVM? It comes with the JDK (look for "jvisualvm.exe" inside your JDK's bin directory) and is capable of profiling local virtual machines automatically as well as remote machines when configured properly. And it does give a pretty slick overview of what threads are running and the code they are spending time in, so I think you could easily do what you need from it. And best of all, it's free :)
As I said, local profiling is a breeze. You just run JVisualVM.exe standalone, and it will find any and all java processes running on the local machine automatically (you can just pick them out of a menu that VisualVM gives you upfront). If you want to profile remotely, set the following VM arguments for whatever it is that you're running:
-Dcom.sun.management.jmxremote.port=[0-65535]
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
Then within VisualVM, use the hostname of the machine your remote JVM is running on and the port you configured in the first VM argument above.

Related

What is JFR parameter filename meaning? File ends up being empty after exit

I have situation where I start JDK18 jvm from c++ code to produce vst plugin goal being to implement audio signal algorithms in java side with added value of full java GUI api. My framework works very smoothly apart from the repeatable state where my audio streaming crashes after 14 hours. So I thought this is good place to start learning JFR. My jvm starting parameters are in xml file and relevant part is:
<param>
-XX:StartFlightRecording,dumponexit=true,filename=c:/out/blackbox.jfr
</param>
Even when application exits that named file keeps empty. So what is the idea of filename parameter if it stays empty and how to use it?
The recording is dumped in a Java shutdown hook. If you terminate the C++ application with exit(status), the Java hook never gets a chance to run.
Not sure how to best run the shutdown hooks, but you could perhaps invoke System.exit(status) from native using CallStaticVoidMethod?
My solution with JDK 18 and flight recorder is not to use JVM startup options at all but instead use jcmd's JFR commands. This is due to incompatible JVM options at startup and lacking documentation. Available documentation is clearly for some older versions of JVM. Here is the available documentation:https://docs.oracle.com/javacomponents/jmc-5-5/jfr-command-reference/toc.htm which proposes use of -XX:+UnlockCommercialFeatures which has been long gone. What is current state of command line options is not achieveable for average programmer.
But "jcmd JFR.start" is example of things that work. I got things working observing with "jcmd PID JFR.check" . It is obvious that JFR api is also little bit broken and needs to addressed in a certain way to get the wanted results. There must have been very hurry when implementing it because the order of parameters is very crucial. And there is a nag that "name" must not be a number even it uses it as number. Now I know it is sensitive. So the way I want it to function is to sample and dump periodic chunks so that differences reveal them selves. Now I have the solution to that but it needs another question with no stupid complaints. Baseline is that jcmd with JFR parameter must be used as it comes out of the box in the way which is not obvious.

Dumping a Java program into a file and restarting it

I was just wondering if it's possible to dump a running Java program into a file, and later on restart it (same machine)
It's sounds a bit weird, but who knows
--- update -------
Yes, this is the hibernate feature for a process instead of a full system. But google 'hibernate jvm process' and you'll understand my pain.
There is a question for linux on this subject (here). Quickly, it's possible to hibernate a process (far from 100% reliable) with CryoPID.
A similar question was raised in stackoverflow some years ago.
With a JVM my educated guess is that hibernating should be a lot easier, not always possible and not reliable at 100% (e.g. UI and files).
Serializing a persistent state of the application is an option but it is not an answer to the question.
This may me a bit overkill but one thing you can do is run something like VirtualBox and halt/save the machine.
There is also:
- JavaFlow from Apache that should do just that even though I haven't personally tried
it.
- Brakes that may be exactly what you're looking for
There are a lot restrictions any solution to your problem will have: all external connections might or might not survive your attempt to freeze and awake them. Think of timeouts on the other side, or even stopped communication partners - anything from a web server to a database or even local files.
You are asking for a generic solution, without any internal knowledge of your program, that you would like to hibernate. What you can always do, is serialize that part of the state of your program, that you need to restart your program. It is, or at least was common wisdom to implement restart point in long running computations (think of days or weeks). So, when you hit a bug in your program after it run for a week, you could fix the bug and save some computation days.
The state of a program could be surprisingly small, compared to the complete memory size used.
You asked "if it's possible to dump a running Java program into a file, and later on restart it." - Yes it is, but I would not suggest a generic and automatic solution that has to handle your program as a black box, but I suggest that you externalize the important part of your programs state and program restart points.
Hope that helps - even if it's more complicated than what you might have hoped for.
I believe what the OP is asking is what the Smalltalk guys have been doing for decades - store the whole programming/execution environment in an image file, and work on it.
AFAIK there is no way to do the same thing in Java.
There has been some research in "persisting" the execution state of the JVM and then move it to another JVM and start it again. Saw something demonstrated once but don't remember which one. Don't think it has been standardized in the JVM specs though...
Found the presentation/demo I was thinking about, it was at OOPSLA 2005 that they were talking about squawk
Good luck!
Other links of interest:
Merpati
Aglets
M-JavaMPI
How about using SpringBatch framework?
As far as I understood from your question you need some reliable and resumable java task, if so, I believe that Spring Batch will do the magic, because you can split your task (job) to several steps while each step (and also the entire job) has its own execution context persisted to a storage you choose to work with.
In case of crash you can recover by analyzing previous run of specific job and resume it from exact point where the failure occurred.
You can also pause and restart your job programmatically if the job was configured as restartable and the ExecutionContext for this job already exists.
Good luck!
I believe :
1- the only generic way is to implement serialization.
2- a good way to restore a running system is OS virtualization
3- now you are asking something like single process serialization.
The problem are IOs.
Says your process uses a temporary file which gets deleted by the system after
'hybernation', but your program does not know it. You will have an IOException
somewhere.
So word is , if the program is not designed to be interrupted at random , it won't work.
Thats a risky and unmaintable solution so i believe only 1,2 make sense.
I guess IDE supports debugging in such a way. It is not impossible, though i don't know how. May be you will get details if you contact some eclipse or netbeans contributer.
First off you need to design your app to use the Memento pattern or any other pattern that allows you to save state of your application. Observer pattern may also be a possibility. Once your code is structured in a way that saving state is possible, you can use Java serialization to actually write out all the objects etc to a file rather than putting it in a DB.
Just by 2 cents.
What you want is impossible from the very nature of computer architecture.
Every Java program gets compiled into Java intermediate code and this code is then interpreted into into native platform code (when run). The native code is quite different from what you see in Java files, because it depends on underlining platform and JVM version. Every platform has different instruction set, memory management, driver system, etc... So imagine that you hibernated your program on Windows and then run it on Linux, Mac or any other device with JRE, such as mobile phone, car, card reader, etc... All hell would break loose.
You solution is to serialize every important object into files and then close the program gracefully. When "unhibernating", you deserialize these instances from these files and your program can continue. The number of "important" instances can be quite small, you only need to save the "business data", everything else can be reconstructed from these data. You can use Hibernate or any other ORM framework to automatize this serialization on top of a SQL database.
Probably Terracotta can this: http://www.terracotta.org
I am not sure but they are supporting server failures. If all servers stop, the process should saved to disk and wait I think.
Otherwise you should refactor your application to hold state explicitly. For example, if you implement something like runnable and make it Serializable, you will be able to save it.

See the java heap content in run time

I am looking for any tool that allows me to see how objects are created on heap in run time.
I was using VisualVM - Profiles but was not able to find when a variable of specific type (the one I am looking for) is being created. Maybe I do something wrong...
I will be also thankful getting any hint how to get such information using any API.
Regards,
Marcin
Typically, profilers (such as JProfiler) will allow you to see this - see for example the Allocation recording explained screencast.
However, they achieve this by attaching an agent to the JVM that allows them to intercept the low-level operations - this information is not usually available to either users or Java programs. As such, you won't be able to see the heap via JMX apps such as JConsole or JVisualVM.
Inside VisualVM Profiler, select the Settings and specify the class you want to profile. May be you also need to look on the option which record allocation stacks.
It sounds like you are trying to debug a program and that using the debugger would be the best option. You should be able to add a conditional breakpoint to stop the program when a variable is assigned the value you are looking for. This will allow you to see all the values at that time and the call stack to see what was called to create it.

An alternative of software like VisualVM to programmatically find running java applications' values etc. by searching heap dumps?

I'm not experienced with java applications but I found out that finding static pointers etc. to these applications' memory addresses is often (nearly) impossible, apparently because of the java engine that handles the code (correct me if this way of naming it is wrong please).
Now, I've used VisualVM (https://visualvm.dev.java.net/) and it's great. I can select my java process and create a heap dump. It then shows me all classes and their values.
Can I use this method to continousely poll the heap dump and receive object values, for example the X Y and Z of a game? How would I programmatically interact with such application, and if this should not be done with VisualVM, what would be an alternative?
Edit: this is what I need to do:
I need to be able to find all classes with properties that have a certain value. For example: I'd search for the X coordinate (a float) and it should return the class "PlayerCoordsHandler" (just an example) and the corresponding float with it's value... or alternatively just a way to find this same float again (after restarting for example). This process does not have to be programmatic, aslong as requesting the value of the now known property (x float) can be retrieved programmatically (for example with a command line utility or reading from a file).
Edit2:
The target application is a windows executable (but made with java) and launches it's own java VM. It's not possible to add java parameters for debugging. This does not seem to be required though, as VirtualVM is able to debug the process just fine. Anyone knows how?
Thanks in advance.
It looks like you want to debug running Java applications.
The "official" Java debugger is JDB. I believe it's part of the JDK. It has the ability to set breakpoints, examine heaps, list and display and even change variables, show running threads and so on. The usual debugger stuff. But it's command line, which makes it a pain in the neck to work with.
Instead, it makes a lot of sense to use an IDE with integrated debugger. I use Eclipse. You can do all the usual debuggery things, including displaying windows with variables. You can set conditional breakpoints and there's much more. Specifically in answer to your question, you can set up watch expressions, which will be evaluated during the program's execution and their displays refreshed with new values when they change.
You may not want to run your Java app inside the IDE; or it may be running in a Web application server. That's no problem for JDB or Eclipse (or other IDEs, like NetBeans or IntelliJ Idea): They can connect to a running JVM and debug remotely with the same level of convenience.
A program being debugged like this, remotely or otherwise, run somewhat more slowly than if it were not. Your game, while being debugged, will run at rather bad-looking FPS; but it should still respond more or less normally to gameplay interaction.
Remote debugging:
To be able to attach your EclipseNetBeans debugger to a running Java process you need to start that process with the following Java options…
-Xdebug -Xrunjdwp:transport=dt_socket,address=3704,server=y,suspend=n
Have a look at YourKit. You can monitor CPU, memory and threads live, and generate dumps whenever you want. It can even compare different memory dumps to show you which objects were added/removed.
It's not free though, it has a 15 day (or 30 day?) fully functional eval period. If free is not a real concern it's definitely a great tool.
I good starting point is the jps and jstat tools added in Java 6 (i think). jps gives you the pid and main class for each application. jstat give you more details about process
Triggering a heapdump is usefull for post-mortem analysis of say memory leaks, but as the Java garbage collector moves objects around, you cannot use the memory values of a heapdump to reliably access those objects.
If you need a way to query internal values from outside of the application you could look into setting up an RMI service API via which you can retrieve the values you need.
Another method (if you just need to test something) could be to connect to the process via de Java debugging API.
If you know the JRE location that is used, you could rename java.exe and write a (C/C++) wrapper that adds the debug options listed by Carl and calls the renamed_java.exe in turn.
Another posibility might be to add or update classes in the .jar file of the application. You do not need the source to do this.
Tom, are you trying to reverse engineer an application that specifically tries to obfuscate its working? If so you might get further if you contact the manufacturer and ask them what possibilities they see for what you try to achieve?
You can easily generate a heap dump by creating your own JMX connection to the JVM, just like VisualVM does it. Analyzing the heapdump is very possible (the data is there and totally disconnected from the JVM so there is no interference from the gc).
However, unless it is a very specific scenario you are looking for you are probably much better off giving the heapdump to MAT and find a good workflow in there to use.
Edit: In this particular case it is probably better to create some kind of specific API to access the values from the outside (and maybe publish the values as MBeans using JMX). Taking a heap dump is way to much work if all you want to do is monitoring a few values.
Edit2: Based on your edits, it seems to me like you could really benefit from publishing your own MBean over JMX. I have to run for a meeting but, unless someone else does it while I am away, I will try to remember to give you some pointers later. Either in an edit of this one or in a new post.
If you want to poll the values of specific objects while your Java application is running you would probably find that using JMX is a better and more efficient approach rather than using a heap dump. With JMX you can define what values should be exposed and use tools such as VisualVM or JConsole to view them at runtime.
With VisualVM and heapdump you can find all classes with certain property by OQL:
var out = "";
var cls = filter(heap.classes(), "/java./(it.name)")
while (cls.hasNext()) {
var cl = cls.next();
var fls = cl.fields;
while (fls.hasMoreElements()) {
var fl = fls.nextElement();
if (/size/(fl.name)) {
out = toHtml(cl) + "." + fl.name + "()\n";
}
}
}
out.toString()
and write custom logging for BTrace
It is alternative for debugging.
FusionReactor could be a good alternative. For example;
VisualVM doesn’t give you a lot of insides on application memory
except for the total Heap allocation. Heap is a good metric to start
with, but I feel this is not enough to troubleshoot the actual cause
of a memory-related issue.
FusionReactor will display all of the memory spaces it detects, which
depends on the version of Java you’re running:
Heap allocation Non-Heap allocation CodeHeap (profiled and
non-profiled methods) Compressed Class Space FusionReactor also shows
the amount of memory that each generation takes Eden Space Old Space
Survivor Space
https://www.fusion-reactor.com/blog/java-visualvm-alternatives/

Are there any Java VMs which can save their state to a file and then reload that state?

Are there any Java VMs which can save their state to a file and then reload that state?
If so, which ones?
Another option, which may or may not be relevant in your case, is to run the JVM (any JVM) inside a virtual machine. Most virtual machines offer the option to store and resume state, so you should be able to restart your PC, fire up the VM when it comes back up and have the Java process pick up from where it was.
I use VMWare Player for testing on IE at work, and this works as noted above when I close and later reopen it. I don't generally do this when apps are doing anything of note in the VM, but as long as they aren't accessing any external resources (e.g. network sockets), I would expect it to work as if the VM was never shut down.
Continuations are probably be what you are looking for:
[...] first class continuations, which are constructs
that give a programming language the
ability to save the execution state at
any point and return to that point at
a later point in the program.
There are at least two continuation libraries for Java: RIFE continuations and javaflow. I know that javaflow at least allows serializing state to disk:
A Continuation can be serialized if
all objects it captured is also
serializable. In other words, all the
local variables (including all this
objects) need to be marked as
Serializable. In this example, you
need to mark the MyRunnable class as
Serializable . A serialized
continuation can be sent over to
another machine or used later. - Javaflow Tutorial
You should serialize relevant domain-specific objects which can be de-serialized by another JVM run-time.
I'm not aware of any tools persisting an entire JVM. The closest I got to doing this was creating a core dump from a running JVM process using gcore, then using jsadebugd, jmap or jstack to debug it.
For instance:
$ jps # get JVM process ID XXX
$ gcore -o core XXX
$ jsadebugd $JAVA_HOME/bin/java core.XXX
UPDATE
I don't think you're going to find a solution that's portable between architectures just yet.
It is worth noting that many objects cannot be serialized as they have state outside the java context.
e.g. Sockets, Threads, Open files, Database connections.
For this reason, it is difficult to to save the state of a useful application in a generic way.
I'm not aware of JVM's that can store state. Depending on your exact needs, you can maybe consider using Terracotta. Terracotta is essentially able to share heap state between JVM's, and store this state to disk.
This can be used to cluster applications, and/or make the heapstate persistent. In effect, you can use it to start the JVM up and pick up where you left off. For more information check out:
http://www.infoq.com/articles/open-terracotta-intro
Hope this helps.
I've worked on an embedded Java project which used this approach to start up quickly.
The JVM was from Wind River, running on top of VxWorks.
Sun has done some research on "orthogonal persistence", which provides "persistence for the full computational model that is definedby the Java Language Specification":
http://research.sun.com/forest/COM.Sun.Labs.Forest.doc.opjspec.abs.html
PJama is a prototype implementation:
http://research.sun.com/forest/opj.main.html
To my knowledge, there is nothing to capture JVM state and restore it, but people are trying to serialize/deserialize the Thread class to achieve something similar. The closest thing to a working implementation I found was brakes, but you may find more when you google for "thread serialization".
I take it you want to be able to resume from where the snapshot was stored, as if nothing thereafter had happened.
I wonder how many framework components and libraries such functionality would break. Suddenly, you are reviving a JVM state from storage; in the meantime, the clock has mysteriously skipped forward by 23 hours, network connections are no longer valid, GUI objects no longer have any underlying O/S handles... I'd say this is nontrivial, and impossible in the general case without modifying the framework extensively.
If you can get away with just storing the state of your in-memory objects, then something like Prevaylor might work for you. It uses a combination of journalling changes to business objects with a serialized snapshot to record the state of your objects, which you can then reload later.
However, it doesn't store the full JVM state (call stack, GC status etc). If you really need that level of detail, then a specialized JVM might be needed.
The answer at this time is no, there are no JVMs that can 'hibernate' like your operating system can or like VMWare et al can.
You could get half-way there, depending on the complexity of your app, by just serializing state out when the program closes and serializing it back in, but that won't do stuff like pause executing some business logic when you close and then continue when you open it again.

Categories