Confused about Java Memory [duplicate] - java

Is the same JVM used by all Java applications running or, does 'one JVM per Java application' apply? (say the applications are IntelliJ IDEA, a server and NetBeans for example)
Further, is there any connection between JVMs assigned and processes used by each Java application?

Generally speaking, each application will get its own JVM instance and its own OS-level process and each JVM instance is independent of each other.
There are some implementation details such as Class Data Sharing, where multiple JVM instances might share some data/memory but those have no user-visible effect to the applications (except for improved startup time, hopefully).
A common scenario however is a single application server (or "web server") such as Glassfish or Tomcat running multiple web applications. In this case, multiple web applications can share a JVM.

There's one JVM per Java application. There shouldn't be any connection between them unless you establish one, e.g. with networking. If you're working inside of an IDE, the code you write generally runs in a separate JVM. The IDE will typically connect the separate JVM for debugging. If you're dealing with multiple web applications they could share the same JVM if they're deployed to the same web container.

In theory you can run multiple applications in a JVM. In practice, they can interfere with each other in various ways. For example:
The JVM has one set of System.in/out/err, one default encoding, one default locale, one set of system properties, and so on.
If one application changes these, it affects all applications.
Any application that calls System.exit() kills all applications.
If one application thread goes wild, and consumes too much CPU or memory it will affect the other applications too.

Short answer: often, yes, you'll get one application per JVM.
Long answer: the JVM can be used that way, and that may be the best option, but it doesn't have to be.
It all depends on what you consider to be an 'application'. An IDE is a good example of an application which is presented to its end users (i.e. us) as a single entity but which is actually comprised of multiple underlying applications (compilers, test runners, static analysis tools, packagers, package managers, project / dependency management tools, etc). In that case there are a variety of tricks which the IDE uses to ensure that the user experiences an integrated experience while also being shielded (to some extent) from the individual vagaries of the underlying tools. One such trick is to do some things in a separate JVM, communicating either via text files or via the application-level debugging facilities.
Application servers (Wildfly, Glassfish, Websphere, Weblogic, etc) are applications whose raison d'etre is to act as containers for other applications to run in. In that case, from one perspective, there's a single JVM per application (i.e. one JVM is used to run the entire application server) but there are actually multiple applications contained within that JVM in their own right, each logically separated from each other in their own classloader (reducing the possibility of accidental in-process crosstalk).
So, it all really depends on what you consider an application to be. If you're purely talking about "the thing which runs when 'main()' is called", then you're looking at one application per JVM - when the OS starts the JVM, the JVM runs a single class's public static void main() method.
But once your applications start getting more complicated your boundaries become more blurred. An IDE such as Intellij or Eclipse will reuse much of the same stuff as 'javac', either in the same JVM or a different one, as well as doing different work (such as repainting the screen). And users of a web application on a (shared JVM) application server may actually be using much the same 'core' application as could be used locally via the command line.

Number of JVMs running is the number of executables invoked.
Each such application invokes its own java executable (java.exe/ javaw.exe etx for windows) which means each is running in a separate JVM.

Any application which has shared libraries will share the same copy of those libraries. Java has a fair amount of shared libraries. However, you won't notice the difference except for some memory saved.

Little late here however this info may be useful for somebody. In a Linux system, if you want to know how many JVMs are running you can try this command
$ ps -ef | grep "[j]ava" | wc -l
ps to list process, grep to search process containing "java" and wc to count lines returned

Actually this is one question that can have very confusing answers. To keep it real short:
Yes per java process, per JVM.
Runtime and ProcessBuilder follow this rule.
Loading jars using reflection and then executing the main won't spawn new JVM.

Related

How jvm distributes between tomcat and deployed Java applications

We have Tomcat deployed with two Java based web applications. How can I tune the performance of one of the applications without affecting the other one if they are running in the same JVM?
Your tomcat run in a JVM with both your applications. All 3 run in the same JVM. So if you tune the JVM (like max memory usage), everything will be affected by it. As far as I know there is no ways to indicate that you want more resources allocated to 1 of your applications.
The two web applications are deployed within the same JVM (including tomcat). So there is just one JVM that tomcat and the two web applications reside in. This is your current scenario.
On the other hand if you would like to tune the web applications separately - say in terms of performance etc. then the easiest thing would be to deploy them on two different hosts / machines. This way the two web applications would be running in their own JVM and would be completely isolated from each other and can be tuned independently. Note: you would need to think this through in terms of requirements of another host and yet another for a reverse proxy. See EJP's comment below.
If that is not possible then you could have two different JVMs brought up each with a tomcat and one of the web applications. This way you could tune the two JVMs separately: you could tune the tomcat servers running separately within the two different JVMs, you could attempt to run them with different allocations of OS resources etc. But that is an involved topic for another discussion. How would you achieve two different JVMs running a tomcat and one of the web application each? To achieve that you utilize the CATALINA_BASE approach wherein the two web applications are deployed to two differently located "webapps" folders. I will not go into details on this but leave you with a link. Note: you might need a reverse proxy as well in this case.
With the two different JVM approach (two different java processes), the respective JVMs can be tuned separately. I prefer this approach as this way it is easier to have separate things like log configurations, restart one without affecting the other and so on.
Since you are talking about performance, let me also mention in passing that whatever approach you might take, keep in mind that that in certain Operating Systems especially linux, you could restrict or allocate resource such as cpu, memory etc. to a particular process (JVM in your case). You could also utilize containers such as Docker to do the same. Maybe you are already aware of this, but I mention for completeness.
you can refer to: tomcat - CATALINA_BASE and CATALINA_HOME variables

Isolation within OSGi

I'm trying to understand the benefits of OSGi and what I can't understand is what happens if one of the user-supplied components crashes (for example with OutOfMemory exception). Will this problem be isolated just to this component or the complete JVM will crash?
OSGi does not provide memory or CPU isolation between bundles or components. All bundles in an OSGi Framework run inside a Java Virtual Machine, and Java itself does not have the capability to offer this kind of isolation. OSGi can only do things that are possible within the standard Java architecture.
If you want greater isolation, then use separate OS processes. Remember though: there is no such thing as perfect isolation. If you run as separate processes there is always the chance that a rogue process can take down the entire OS. Even if you run on a separate computer in the same datacentre, then the next power cut or tsunami will affect both computers. So you have to ask yourself how much isolation is needed, and what specific risks you need to mitigate.
For what it's worth, there was an attempt within Java a long time ago to provide memory and CPU isolation. This was JSR-121 (Application Isolation API) and it was never adopted into Java SE. Some vendors such as IBM and Waratek implemented proprietary isolation/multitenancy, but these did not catch on (Waratek later pivoted to application security). Basically you end up implementing a process scheduler within the JVM, and what's the point when the OS already has a good one?
OSGi isolates components at classloader level, and an OutOfMemoryError occurs at JVM level. OSGi does not provide "memory isolation". To answer shortly: the whole JVM will crash.
OSGi Isolation is related to the class resolution and class loading. JVM process itself is shared. So OOM Exception will affect your whole container
If you want to run a 3rd party component, you may want to create a new instance (managed from your root container), it runs as a separate OS process with separate JVM parameters.

Running a java program multiple times from command prompt

If i run a same multithreaded program from multiple command prompt, what would happen? Each command prompt will run in diffrent jvm. how the shared resources will access by threads in different jvm?
If i run a same multithreaded program from multiple command prompt,
what would happen?
there is seperate JVM for each program or application. (whether application is same or different)
how the shared resources will access by threads in different jvm?
As Same multithreaded application is executed by different JVM there is nothing(resources) to share by different JVM's.
As there are different java application are running same time(multiprocessing) shared resources of machine(memory , processor etc.) are handled by OS.
Note:IF you are asking about shared resources in single multithreaded application please refer oracle docs
Assuming the JVM isn't doing voodoo magic (knowing Oracle I can't be sure) each instance of Java would be running it's own thing and allocating it's own resources. As for how the host handles threading and resource distribution is a whole nother subject with tons of discussion and no good answer on how to do it (other than "Correctly")
To share resources among different JVM you need an external player, a Redis DB or similar, however if your program is multithread, why do you need to run different process ? Why don't you run it just one time ?
Each command prompt will run in diffrent jvm - Yes.
Among different jvms Resource sharing will be decided by operating system.
If two instances of JVM run the same multi threaded application, you cannot do resource sharing. Remember, resource sharing and concurrency control is between multiple threads running a single JVM process. Two such JVM processes, running the same application code, cannot do any concurrency control and resource sharing. For example, if the first JVM process opens a file, the second JVM process will not be able to access that file.
I hope this answers your question. If there is something specific which you are trying, then describe that, so that, we can offer you suggestions.

Setting the multiple JREs in the same application

I have implemented one application using JDK 1.6 64-bit, JSF, Tomcat server 64-bit etc at user system.I am integrating some devices(i.e. finereader, scanner, etc) into this application. Some of devices libraries are supported only on JRE 32-bit Only.
So, device integrated screens to be run on JRE 32-bit and non device screens should be run on a JRE 64-bit. Can I configure multiple JRE's in the same application? If possible, how?
A Java application runs in a JVM. The JVM is part of one single JRE. You could split your application into two parts, which each run in their own JVM. These applications then would have to communicate with each other to coordinate the user experience. This does not look like a good solution to me.
It all depends on how you define "application."
First, in regard to your question, each JVM instance runs a single kind of Java--32 or 64 bit--Java version and such.
Sometimes, an application consists of a single JVM running a single java executable, usually a jar and some stuff on the classpath with a single 'main'
Sometimes, an application consists of multiple JVMs running on one or more boxes. In this case, each JVM is running a single java executable. But there has to be some sort of communication between these executable parts to make it function as an application.
Alternatively, the same executable might run on multiple JVMs and we still call it one application. In this case, there would be some sort of outside stuff that decides how to allocate the work of the application amoung the multiple JVMs. For example, you could run 18 instances of Tomcat on 9 boxes with a hardware load balancer dividing up the network requests and assigning each one to one of the Tomcat instances. In this case, though, part of the application is probably running on 1000's of user's computers inside a browser.
Sometimes, we say multiple applications are running under another application. In this case, we might call the master application a container. One example is Tomcat. In this case, Tomcat manages the load of requests for each of the separate applications because the HTTP requests come in off the network with information in the header indicating which one handles that request.
You already say that you have some code running under Tomcat. Tomcat is a single executable (It runs in one JVM and has one variety of Java) and it manages running your one Java executable supplied as a .war file, usually. There could be other Java applications running in other JVMs that communicate through that Tomcat and with your executable. Or there might not be other JVMs that your executable communicates with running somewhere else.
So, you can see, the real answer is "it depends." If you have multiple JVM communicating in some way, you could have different Java varieties. If it's all running under a single Tomcat instance, then you have a single variety of Java.

Why have one JVM per application?

I read that each application runs in its own JVM. Why is it so ? Why don't they make one JVM run 2 or more apps ?
I read a SO post, but could not get the answers there.
Is there one JVM per Java application?
I am talking about applications launched via a public static void main(String[]) method ...)
(I assume you are talking about applications launched via a public static void main(String[]) method ...)
In theory you can run multiple applications in a JVM. In practice, they can interfere with each other in various ways. For example:
The JVM has one set of System.in/out/err, one default encoding, one default locale, one set of system properties, and so on. If one application changes these, it affects all applications.
Any application that calls System.exit() will effectively kill all applications.
If one application goes wild, and consumes too much CPU or memory it will affect the other applications too.
In short, there are lots of problems. People have tried hard to make this work, but they have never really succeeded. One example is the Echidna library, though that project has been quiet for ~10 years. JNode is another example, though they (actually we) "cheated" by hacking core Java classes (like java.lang.System) so that each application got what appeared to be independent versions of System.in/out/err, the System properties and so on1.
1 - This ("proclets") was supposed to be an interim hack, pending a proper solution using true "isolates". But isolates support stalled, primarily because the JNode architecture used a single address space with no obvious way to separate "system" and "user" stuff. So while we could create APIs that matched the isolate APIs, key isolate functionality (like cleanly killing an isolate) was virtually impossible to implement. Or at least, that was/is my view.
Reason to have one JVM pre application, basically same having OS process per application.
Here are few reasons why to have a process per application.
Application bug will not bring down / corrupt data in other applications sharing same process.
System resources are accounted per process hence per application.
Terminating process will automatically release all associated resources (application may not clean up for itself, so sharing processes may produce resource leaks).
Well some applications such a Chrome go even further creating multiple processes to isolate different tabs and plugins.
Speaking of Java there are few more reasons not to share JVM.
Heap space maintenance penalty is higher with large heap size. Multiple smaller independent heaps easier to manage.
It is fairly hard to unload "application" in JVM (there to many subtle reasons for it to stay in memory even if it is not running).
JVM have a lot of tuning option which you may want to tailor for an application.
Though there are several cases there JVM is actually shared between application:
Application servers and servlet containers (e.g. Tomcat). Server side Java specs are designed with shared server JVM and dynamic loading/unloading applications in mind.
There few attempts to create shared JVM utility for CLI applications (e.g. nailgun)
But in practice, even in server side java, it usually better to use JVM (or several) per applications, for reasons mentioned above.
For isolating execution contexts.
If one of the processes hangs, or fails, or it's security is compromised, the others don't get affected.
I think having separate runtimes also helps GC, because it has less references to handle than if it was altogether.
Besides, why would you run them all in one JVM?
Java Application Servers, like JBoss, are design to run many applications in one JVM

Categories

Resources