Strange behavior re-runing java application in a loop - java

Unix daemon runs a script a loop, the script calls a java program: java {java_args} myClas.jar
The java program is heavy program with multiple threads.
The problem is very strange: First execution works as expected.
But the second execution is stuck some where and I can't find a reason (very hard to debug this).
Is there a possibility that when first execution is finished there are still not-cleaned resources or threads left from this execution?
If yes, is it possible to clean and kill everything right after process completes?

If by resources, you mean threads, then no. When the VM shuts down, everything on the heap, all threads, objects and monitors are disposed of. However if you're depending on the existence/absence of a file for locking or something similar, a deadlock is possible. Also, is it possible that the first process is still running when you launch the second one?
If your java process is stuck on the second run, you can attach jvisualvm to it and should be able to figure out where it's stuck.

Related

Threads in Java VS Threads in Application Server/Tomcat

From the Head First Java book, I know that threads in java doesn't run parallelly, but JVM just switches between the threads which seem to us like running parallelly. And these threads run in a single JVM which itself a process that runs in one core of the Computer.
Here is the content from the book - " With more than one call stack, you get the appearance of having multiple things happen at the same time. In reality, only a true multiprocessor system can actually do more than one thing at a time, but with Java threads, it can appear that you’re doing several things simultaneously. In other words, execution can move back and forth between stacks so rapidly that you feel as though all stacks are executing at the same time. Remember, Java is just a process running on your underlying OS. So first, Java itself has to be ‘the currently executing process’ on the OS. "
My doubt is, does the tomcat threads and application server threads which are created per user request are also not run parallelly but JVM which runs on a single core (on which application server runs) just switches between the threads?
OR does threads really run parallelly on different cores?
I have been struggling with this question since many days. I have googled lot about this, but couldn't find the answer. So posting it here, hoping someone can help me.
Thank you.

java Process fails if process is ptrace ATTACH

I'm having the strangest problem: maybe someone can help out.
I have a daemon written in Java (I've tried the latest Java 8 both OpenJDK and Oracle) on Linux. It will spawn some processes and there is a thread which watches to see if they're complete, meanwhile it will run other commands, some of which may kill the processes, etc.
Everything works absolutely fine almost all the time. However, one of the operations that the daemon can perform on its subprocesses is it can grab a core from them (without killing them: a core of the active process). It does this by loading a .so and calling it via JNI, which uses ptrace(PTRACE_ATTACH...) to pause the subprocess and grab core information, then it uses ptrace(PTRACE_DETACH...) to let it run again.
This also works fine and I can see the process operates correctly after the core has completed and all is fine.
Except, Java's Process object is now all wonky. Whenever I invoke exitValue() on this process once this has happened I always get back and exit code of 4991 (which if you decode it, means WIFSTOPPED with a signal value of 19, or SIGSTOP). That's not entirely surprising since the Linux man page states that ptrace() will look to parents as WIFSTOPPED. But the problem is that once the Process object reaches this state, it will never do anything else, even though the process actually goes back to running after the detach.
Even more critically, even after the process really exits, exitValue() still returns 4991, and the process is not reaped (it lives on in Z (zombie) state, as defunct) and will never go away, until my daemon is killed whereupon init will inherit, and reap, the zombie processes.
I've looked at the value of isAlive() (says no) and I've tried to run waitFor(0, TimeUnit.SECONDS) (says not running) but none of them get Process out of this broken state--this doesn't surprise me too much since my reading suggests these methods are actually implemented in terms of the exitValue() method anyway.
This appears to me like a bug in Java Process but I'm not sure... I've tried reproducing it by attaching GDB to the process then detaching it, but that doesn't show the same problem. Similarly just using SIGSTOP / SIGCONT doesn't do it.
Anyone have any hints or thoughts?

Is there a Linux command to print the current stack of a running Java process

Situation:
I have a Java1.7 process running in CentOS6 with multiple threads. The process currently halts (i.e., stuck in some kind of loop or waiting function). Due to the complexity nature of the program, it is difficult to do a routine debug in, for instance, Eclipse (more explanation in the background section below). Therefore, I'd like to debug the code by tracing the current running stack.
Question:
Is there a Linux command that would allow me to print the stack to identify the thread/method that is currently running such that I can find which method is causing the halt?
Background:
The reasons for not being able to debug in Eclipse:
It is a MapReduce program typically run on multiple computers.
Even if I use run on one computer, it still involves multiple threads running simultaneously.
Most importantly, the "halting bug" occurs randomly (i.e., not being able to reproduce). So my best shot is to identify the current running method that caused the bug.
P.S. My approach may be completely wrong, so feel free to correct me and point me in the right direction.
Thanks for your help.
You can use JStack to get the current thread dump. It should give you currently running threads and their stack traces.
It will even do more for you - should there be any deadlocks present it will tell you about them.
Apart from that you can also use JVisualVM to monitor your application in real time (you can check threads in real time there and take thread dumps from it).
From RedHat:
Following are methods for generating a Java thread dump on Unix:
1) Note the process ID number of the Java process (e.g. using top, a
grep on ps -axw, etc.) and send a QUIT signal to the process with the
kill -QUIT or kill -3 command. For example:
kill -3 JAVA_PID

Java exit a program without quitting JVM

I want to exit a java process and free all the resources before it finishes its normal running, if a certain condition is meet. I dont however want to quit JVM, as I have other java programs running at the same time. Does return; do the above, or is there a better way to do it?
Thanks.
There is one JVM process per running Java application. If you exit that application, the process's JVM gets shut down. However, this does not affect other Java processes.
You need to understand the JVM mechanism and clarify the terminology.
Let's use the following as datum for the terminology.
Threads are divisions of concurrently processed flows within a process.
A process is an OS level thread. The OS manages the processes. A process is terminated by sending a termination signal to the OS management. The signal may be sent by the process itself or by another process that has the applicable privilege.
Within a process, you can create process level threads. Process level threads are normally facilitated by the process management of the OS, but they are initiated by the process and terminated by the process. Therefore, process level threads are not the same as processes.
An application is a collection of systems, programs and/or threads that cooperate in various forms. A program or process within an application may terminate without terminating the whole application.
Within the context of JVM terminology, program may be one of the following.
A program is run per JVM process. Each program consumes one JVM process and is invoked by supplying the classpath of java bytecode and specifying the main entry point found in the classpath. When you terminate a java program, the whole jvm process that ran that program also terminates.
A program is run per process level thread. For example, an application run within a tomcat or JEE server is run as a thread within the JEE process. The JEE process is itself a program consuming one JVM process. When you terminate an application program, the JEE process does not terminate.
You may initiate process level threads within a java program. You may write code that terminates a thread but that would not terminate the process (unless it is the last and only running thread in the process). The JVM garbage collection would take care of freeing of resources and you do not need to free resources yourself after a process level thread is terminated.
The above response is simplified for comprehension. Please read up on OS design and threading to facilitate a better understanding of processes and the JVM mechanism.
If the other threads running concurrently are not daemon threads, leaving main will not terminate the VM. The other threads will continue running.
I completely missed the point though.
If you start each program in a separate JVM, calling System.exit() in one of them will not influence the others, they're entirely different processes.
If you're starting them through a single script or something, depending on how it is written, something else could be killing the other processes. Without precise information about how you start these apps, there's really no telling what is going on.
#aix's answer is probably apropos to your question. Each time you run the java command (or the equivalent) you get a different JVM instance. Calling System.exit() in one JVM instance won't cause other JVM instances to exit. (Try it and see!)
It is possible to create a framework in which you do run multiple programs within the same JVM. Indeed this is effectively what you do when you run a "bean shell". The same sort of thing happens when your "programs" are services (or webapps, or whatever you call them) running in some application server framework.
The bad news is that if you do this kind of thing, there is no entirely reliable way make an individual "program" go away. In particular, if the program is not designed to be cooperative (e.g. if it doesn't check for interrupts), you will have to resort to the DEPRECATED Thread.stop() method and friends. And those methods can have nasty consequences for the JVM and the other programs running in it.
In theory, the solution to that problem is to use Isolates. Unfortunately, I don't think that any mainstream JVMs support Isolates.
Some common usecases leading these kind of requirements can be solved through tools like Nailgun, or Drip.
Nailgun allows you to run what appears to be multiple independent executions of a commandline program, but they all happen in the same JVM. Therefore repeated JVM start-up time does not have to be endured. If these execution interact with global state, then the JVM will get polluted in time and things start to break up.
Drip will use a new JVM for each execution, but it always keeps a precreated JVM with the correct classpath and options ready. This is less performant, but it can guarantee correctness through isolation.

How to check whether an executable JAR has finished in another JVM

guys, I encounter a confusing issue! I want to invoke a executable JAR to compute PI from my main java applicaion using runtime.exec(), which create a new JVM for running the executable JAR. My issue is that when the PI computation is done, the JVM is still alive. my main java application has no idea whether PI computation is finished or not. And I also want when the PI computation is done, the JVM could be shutdown! How can I implement that! ThankS!!
When you call Runtime.exec() you will get a Process object back. You need to call waitFor() on this.
You will also need to capture the stdout/stderr streams (in separate threads to prevent blocking - see this answer for more info).
This all leaves aside why you're doing this in a separate JVM, and why you can't load the relevant classes into your current app and run the library locally.
To answer the second part of your question, the JVM always exits when no non-daemon threads are still running. Or in plainer speech, when your application is "done" and the main method exits without leaving any threads running in the background, the JVM will finish.
This is true regardless of whether you launch the Java process yourself from your desktop/command line, or fire it off via Runtime.exec() (which is broadly equivalent). So when your Pi calculation terminates it will shut down the JVM you spawned, and when your original program finishes then its JVM will also exit.
Though I agree completely with Brian here, I can't see the benefit in running a Java app as a separate process when you should be able to just run it in the original JVM (barring some really unusual environmental stuff such as setting niceness or processor affinity of the various processes).
check what the jar does when you run it standalone, maybe its waiting for input and therefor it will never exit

Categories