Java exit a program without quitting JVM - java

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.

Related

Can a single Java thread take down entire JVM?

If a Java process hangs (due to bug in JNI (faces deadlock), Can it result in blocking of entire JVM? i.e. all processes and threads getting blocked?
due to bug in JNI Yes. If you call into native code a bug can easily bring down the entire JVM (or block everything).
No. The thread or threads in deadlock will remain blocked, but other threads can run independently in other programs or even in the same program. Obviously deadlocks should be avoided whenever possible, but the affected threads will only be the threads in deadlock and any and all threads waiting on the completion of those threads.
Normally every application has it's own JVM instance running. So you could not crash other applications by trying to crash your current JVM . However some application share one JVM like a Web server for instance.
Another scenario would be if it crashes anything on an operating system level. Well then everything related to that will shut down.

Whether JVM runs in User Process or Separate Process

I have read JVM as a Process and as a deamon thread and
As per Java, Each process has its own JVM and Garbage collector
Could some one please explain me with more details on this.
"Whether JVM runs on User Application Process or in Separate process." ??
Everywhere, I read it as an instance for Application Process.
And I also read it as GC has multiple threads.
Whether GC is a separate process or it creates threads on User process.?
JVM is running inside a process that was started by executing java.exe/javaw.exe on Windows or the java executable for Unix/GNU. Its owner would be the one that runs the executable. If two java programs are running then two JVMs in different processes will be created.
GC is a thread inside the JVM, see here
For example, the Java garbage collector is a daemon thread.
A JVM can be started from within an existing process via JNI_CreateJavaVM. A JVM generally consists of multiple threads, whether it runs within an owning process or as a separate process. The term "application" is on a different abstraction level than processes and threads.

How do JVM threads and linux proc threads interact? [duplicate]

How do I distinguish running Java threads and native threads?
In Linux there will be Parent process for every child process, and they say 0 is the parent of all the process, will there be a Parent thread of all the forked Java threads?
How do I know which Java thread is related to OS thread (if a Java thread forkes a native process thread).
Is there any naming convention of Java threads and OS threads?
Can a running Java threads can be suspended or killed from another Java code?
On Linux, Java threads are implemented with native threads, so a Java program using threads is no different from a native program using threads. A "Java thread" is just a thread belonging to a JVM process.
On a modern Linux system (one using NPTL), all threads belonging to a process have the same process ID and parent process ID, but different thread IDs. You can see these IDs by running ps -eLf. The PID column is the process ID, the PPID column is the parent process ID, and the LWP column is the thread (LightWeight Process) ID. The "main" thread has a thread ID that's the same as the process ID, and additional threads will have different thread ID values.
Older Linux systems may use the "linuxthreads" threading implementation, which is not fully POSIX-compliant, instead of NPTL. On a linuxthreads system, threads have different process IDs.
You can check whether your system is using NPTL or linuxthreads by running the system's C library (libc) as a standalone program and looking under "Available extensions" in its output. It should mention either "Native POSIX Threads Library" or linuxthreads. The path to the C library varies from system to system: it may be /lib/libc.so.6, /lib64/libc.so.6 (on 64-bit RedHat-based systems), or something like /lib/x86_64-linux-gnu/libc.so.6 (on modern Debian-based systems such as Ubuntu).
At the OS level, theads don't have names; those exist only within the JVM.
The pthread_kill() C function can be used to send a signal to a specific thread, which you could use to try to kill that specific thread from outside the JVM, but I don't know how the JVM would respond to it. It might just kill the whole JVM.
There is no standard; this completely depends on the Java implementation which you're using. Also, don't mix up "native threads" and "native processes". A process is an isolated entity which can't see into the address space of other processes. A thread is something which runs in the address space of a native process and which can see into the memory of other threads of the same process.
What you see on Linux is something else: Some versions of Linux create an entry in the process table for each thread of a parent process. These "processes" aren't real processes (in the isolation sense). They are threads which can be listed with the ps command. You can find the process which created them by using the parent PID (PPID).
There is no generic solution how Java threads are mapped to OS threads, if at all. Every JVM implementation can do it in a different way.
There is also a pure Java thread implementation, called green threads. This is used as a fallback if native threads aren't supported or the system isn't multithreaded at all. You won't see any green threads at your OS.
Can a running Java threads can be suspended or killed from another Java code ?
If they are running at the same JVM, yes, with stop(). But that's not a good solution and may work, or not. interrupt() allows the thread so safely shut itself down.
There is no way to kill threads outside of the JVM I know of. If a OS really supports killing of threads, I wouldn't expect the Java application to run correctly afterwards!
Can a running Java threads can be
suspended or killed from another Java
code ?
In theory yes. In practice, the Thread.kill() and Thread.suspend() methods are deprecated because they are unsafe except in very limited situations. The basic problem is that killing or suspending a Java thread is likely to mess up other threads that depend on it, and shared data structures that it might have been in the middle of updating.
If "another Java code" is meant to mean another JVM, then the chances of it working are even less. Even if you figured out how to send the relevant thread signal, the results are completely unpredictable. My bet is that the "target" JVM would crash.

what is it meant by stop the JVM with exit()?

They could be many JVMs per Operative system or it is only one JVM per Operative System ? I also read that with "Runtime.exit()", we stop the execution of a JVM?
I'm a bit confuse because I've always thought that JVM is a machine that never stop working, always awaken waiting to be called for example by the "java App.class".
The JVM is an abstract concept, and there may be many running instances per Operating System. The implementation is usually through the Java Runtime Environment. And when exit is called, the runtime stops. The JVM can certainly stop. And (on most computers) it has to be explicitly started.
i'have always thougth that JVM is a machine that never stop working, always awaken waiting to be called for example by the "java App.class"
No, that is not how the JVM works. It's not a background process that is waiting to execute your Java programs. There is not always just one JVM running on one computer.
Whenever you start a Java program, a new JVM is started. When you have multiple Java programs running at the same time, you have multiple JVMs running. Each program is running in its own JVM.
System.exit() stops the JVM that is running the current Java application. It has no effect on other Java programs running on the same machine.
If you start a java app (directly or indirectly with the java shell command), then an instance of the JVM is created and started.
When the application finishes (either by reaching the end or through System.exit() then the JVM instance stops.
Of course, you can have multiple Java apps running simultaneously. Each will be in its own JVM instance.
They could be many JVMs per Operative system or it is only one JVM per Operative System ?
You can do either. You can run a JVM for each command, or you can use an application server to run your java applications. (You cna have more than one application server)
I also read that with "Runtime.exit()", we stop the execution of a JVM ?
This triggers the JVM to shutdown. The process does some work such as calling Shutdown Hooks after this is called.
i' m a bit confuse because i'have always thougth that JVM is a machine that never stop working,
It can be used that way. For example scala has a daemon compiler which is used to compile scala programs.
always awaken waiting to be called for example by the "java App.class".
When you run any program, (java or not) this always starts a new program. The only time this doesn't happen is for built in shell commands. e.g. set

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