I understand that each java process runs in its own JVM. For example when I run jcmd in my machine, I see
21730 sun.tools.jcmd.JCmd
77558 /usr/local/opt/jenkins-lts/libexec/jenkins.war --httpListenAddress=127.0.0.1 --httpPort=8080
99974
99983 org.jetbrains.jps.cmdline.Launcher /Applications/IntelliJ IDEA.app/Contents/lib/asm-all-7.0.1.jar:/Applications/IntelliJ IDEA.app/Contents/lib/lz4-java-1.6.0.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/java/lib/aether-connector-basic-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/java/lib/plexus-utils-3.0.22.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/java/lib/aether-api-1.1.0.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/java/lib/javac2.jar:/Applications/IntelliJ IDEA.app/Contents/lib/util.jar:/Applications/IntelliJ IDEA.app/Contents/lib/platform-api.jar:/Applications/IntelliJ IDEA.app/Contents/lib/qdox-2.0-M10.jar:/Applications/IntelliJ IDEA.app/Contents/lib/jna.jar:/Applications/IntelliJ IDEA.app/Contents/lib/trove4j.jar:/Applications/IntelliJ IDEA.app/Contents/lib/nanoxml-2.2.3.jar:/Applications/IntelliJ IDEA.app/Contents/lib/jdom.jar:/Applications/IntelliJ IDEA.app/Contents/lib/netty-common-4.1.41.Final.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/java/lib/aet
How is the JVM created per app ? Like what happens when I start jenkins with java -jar jenkins.war. Does some process copy over JVM stuff from JRE folder and initialize an instance of JVM ?
When you start a program like java, the operating system creates a "process". A process is the representation of a live, running program. The process concept is what allows you to run several copies of a program at the same time. Each process has its own private memory space and system resources like open files or network connections. Each process can load a different set of dynamically linked libraries. With Java, much of the jvm is implemented in shared libraries, which the launcher program "java" loads in at run time.
The details are OS dependent and become complicated fast.
One of the things that happen when the process is started is that the executable file is mapped into memory. The CPU cannot execute instructions that are on disk or other external storage, so the program "text" has to be copied from disk into main memory first. Mapping the file into memory simplifies this and makes it more efficient: If the CPU needs to access a memory location that's not actually in RAM, the memory manager unit (MMU) issues a "page fault". The page fault causes data to be loaded into RAM. This is more efficient than simply copying the program text into RAM (what if not all text is needed all the time) and also simplifies the overall system (the virtual memory system is already needed for other OS features)
Related
When we write code on a notepad or any IDE, all info is converted to bits on RAM. And the .class file after compilation already has instructions that jvm can understand. This info is also already on RAM when a .class file is created.
So why would jvm need special memory space on RAM called method area for "loading class data".
I learned that method area has metadata related to a class we execute.
But why would u need more memory space when u already have .class file info present on RAM when we run it.
Is it just for faster computing? Or the info on method area is totally different from what I understand.?
When we write code on a notepad or any IDE, all info is converted to bits on RAM.
All data on a computer is bits in RAM at some stage.
And the .class file after compilation already has instructions that jvm can understand. This info is also already on RAM when a .class file is created.
It's not in RAM until the class file is created. The data in the class file is what is in RAM when the code is compiled.
So why would jvm need special memory space on RAM called method area for "loading class data".
It has to be somewhere, and since it has a different lifecycle to other types of data it makes sense to manage it differently.
I learned that method area has metadata related to a class we execute. But why would u need more memory space when u already have .class file info present on RAM when we run it.
You might need to unpack the information or turn it into native code for optimisation.
Is it just for faster computing?
Yes, re-reading the .class file every time which be very slow.
Or the info on method area is totally different from what I understand.?
It stores the information derived from the .class files as well as how the methods in the class are used.
I think you're getting confused by the fact that modern operating systems have a virtual memory system. When you compile Java code the generated bytecodes will be held in physical memory as the compilation takes place. However, the compiler has its own virtual address space. The virtual memory system maps physical addresses to process-specific virtual addresses. It also ensures that other processes cannot read or modify physical memory used by other processes (unless you use a special arrangement called shared memory).
When the JVM is running it has its own virtual memory address space and loads all the class file information into that address space. To keep things organised it puts this data in the method area.
Theoretically, you could just read the compiled code directly from the area of memory used by the compiler process but it would be so complicated to make that work (and an unusual situation) that it is not done this way.
I'm fairly new at this stuff, but essentially: there are programs and there are processes. A program is a file that spawns a process, when executed.
You can't delete a program if there is a process still associated to it. The process needs to be killed first.
This seems to be the case for Java programs too. However I'm curious as to why - isn't the entire thing loaded into the JVM anyway?
"Deleted file" involves som OS-semantics. Under Unix/Linux a file may be deleted and all open file handles stay valid. When the last open file handle vanishes, the space occupied by the deleted file is returned to the pool of free space.
Under Windows there may be other mechanisms.
The JVM works as a Just-In-Time (JIT) compiler. There are many sources of information on JIT compilation, but basically as a java program is running it will encounter parts of the program that are needed, these pieces of the program are in .class files. These .class files is just an intermediate form of Java code (it's not quite Java code, but not quite machine code, yet). Obviously, compiling at runtime (JIT) takes resources (CPU cycles) and, thus, time. So, the JVM only loads pieces of the program that it needs to minimize wasted CPU cycles.
But yes, your understanding of process/programs is correct. To sum up: A process is a running instance of a program. This running program, then can spawn even more processes or threads to perform work.
By reading this article, I know that each java application will run in a specific Java Virtual Machine Instance. So if I execute the following commands("Java -jar test1.jar","Java -jar test2.jar", I will get two processes in the system. And If each command used the default heap size, for example, 256M. The total memory cost is 512M, is that right?
Also I have other questions:
Is the Java virtual Machine a daemon process, start up with the system?
When I execute "java -jar test1.jar", it will create an instance of Java Virtual Machine, then execute the main function. Does it mean every running java application is a sub thread or process of Java Virtual Machine?
Is each running java application individual, other application can not get variable, method, constant, etc, from this running java application?
If one running java application is crashed, will it affect other running java application?
PS: I googled and got lots of different answers, I was totally confused. Anyone who can help me on this kind of questions or even more depth of Java virtual Machine. For example, How it works.
The JVM is a standard process, just like any other. As such there's no implicit communication or state sharing between the two. Each will have their own heap, threads etc. If you kill one it won't affect the other.
What will get shared are the code pages of the JVM itself. The kernel is intelligent enough to identify the same binary (any binary -not just the JVM) running twice and reuse the image. This only applies to the actual binary code - not its state. See here for more info re. Linux.
The JVM isn't a daemon process, but could be started upon system startup as a Windows service or Unix/Linux process (via /etc/init.d scripts). This is how you'd (say) run a web service written in Java when a machine is booted up.
1) No, but there a ways to launch java applications as services with wrappers (Google for "Java service").
2) Yes.
3) You can use communication between processes (v.g. HTTP). But there are no shortcuts due to all processes being run in JVM.
4) No
For the OS, JVM like an user application. Each JVM Instance is individual.
No. JVM is normal process as others.But you can run it as deamon process.
Yes. Java application run on JVM just like you application on OS.
Yes. Each JVM thread is individual, but they can communication whith other JVMs through network,RMI...
It depends. Normally they are individual, but if a JVM crash cause the OS crash, other JVMs will be effected.
I currently work in a Weblogic Java EE project, where from time to time the application executes a Perl script to do some batch jobs. In the application the script is getting invoked as
Process p = Runtime.getRuntime().exec(cmdString);
Though it is a dangerous way to run, but it was working properly until we had a requirement to execute the script synchronously under a for loop. After a couple of run we are getting
java.io.IOException: Not enough space as probably OS is running out of virtual memory while exec-ing under a for loop. As a result we are not able to run the script at all in the server.
I am desperately looking for a safer and better way to run the Perl script, where we don't need to fork the parent process, or at-least not to eat-up all swap space!
The spec is as follows:
Appserver - Weblogic 9.52
JDK - 1.5
OS - SunOS 5.10
Sun-Fire-T200
I've had something similar on a couple of occasions. Since the child process is a fork of the (very large parent it can see all of it shares all it's memory (using copy on write). What i discovered was that the kernel needs to be able to ensure that it could copy all of the memory pages before forking the child, on a 32bit OS you run out of virtual head run really fast.
Possible solutions:
Use a 64Bit OS and JVM, pushes the issue down the road so far it doesn't matter
Host your script in another process (like HTTPD) and poke it using a HTTP request to invoke it
Create a perl-server, which reads perl scripts via network and executes them one by one.
If you want to keep your code unchanged and have enough disk free space, you can just add a sufficiently large swap area to your OS.
Assuming you need 10 GB, here is how you do it with UFS:
mkfile 10g /export/home/10g-swap
swap -a /export/home/10g-swap
echo "/export/home/10g-swap - - swap - no -" >> /etc/vfstab
If you use ZFS, that would be:
zfs create -V 10gb rpool/swap1
swap -a /dev/zvol/dsk/rpool/swap1
Don't worry about that large a swap, this won't have any performance impact as the swap will only be used for virtual memory reservation, not pagination.
Otherwise, as already suggested in previous replies, one way to avoid the virtual memory issue you experience would be to use a helper program, i.e. a small service that your contact through a network socket (or a higher level protocol like ssh) and that executes the perl script "remotely".
Note that the issue has nothing to do with a 32-bit or 64-bit JVM, it is just Solaris doesn't overcommit memory and this is by design.
On Linux & Mac, is there a way to pre-cache the JVM - either in RAM, or a state of it, so that when I start a Java program, it starts as fast as C/C++ programs?
I am willing to waste memory to make this happen.
No. Unfortunately :(
On second thought, the reason why Java programs start faster on Windows these days, is because there is a process (Java Quickstart) which aggressively keeps a copy of the runtime library files in the memory cache which apparently helps immensely. I do not know if this approach has been ported to Linux.
Would that not load the JVM binary and
libs into memory so that they can be
shared?
Yes, but only in the same JVM instance. So you have to load your application into this instance, as servlet container do.
The whole bootleneck of the JVM invocation is class loading, that is the reason for the Java Quickstart that Thorbjørn mentioned.
So you can put the class libs on faster media (ram disk) this will probably fasten your (first) startup. I once installed Netbeans + JSDK on a RAM disk and it starts really fast but once started it will run equal fast than loaded from disk.