Handling of JVM class loading mechanism and class cache Problems

Source: Internet
Author: User

Handling of JVM class loading mechanism and class cache Problems

When a Java project is started, JVM will find the main method, load the class file and the class file in the referenced jar package based on the call between objects (The steps include loading, verification, preparation, parsing, initialization, use, and uninstallation ), in the method area, the memory is used to store the data structure of the class Runtime (including static variables, static methods, constant pools, and class structures ), at the same time, the corresponding Class object is generated in the heap to point to the corresponding Class runtime data structure in the method area.

In the simplest sentence, the class loading process is that the JVM reads the class bytecode file through the IO stream based on the path of the required class file, and inject it into the memory through a series of parsing initialization steps. Java classloaders include BootstrapClassLoader (top layer), ExtClassLoader, AppClassLoader, and user-defined ClassLoader (bottom layer ). JVM loads different types of jar packages (or class files. The relationship is as follows:

BootstrapClassLoader: JAVA_HOME/jre/lib/resources. jar: JAVA_HOME/jre/lib/rt. jar: JAVA_HOME/jre/lib/sunrsasign. jar: JAVA_HOME/jre/lib/jsse. jar: JAVA_HOME/jre/lib/jce. jar: JAVA_HOME/jre/lib/charsets. jar: JAVA_HOME/jre/lib/jfr. jar: JAVA_HOME/jre/classes ExtClassLoader :.. /Java/Extensions :.. /JAVA_HOME/jre/lib/ext :.. /Library/Java/Extensions:/Network/Library/Java/Extensions :.. /S Ystem/Library/Java/Extensions: ../lib/java AppClassLoader is used to load the classes created under ClassPath in our project and the classes referenced in the jar package.
 

The entire class is loaded through a mechanism called Parent-Child delegation.

For example, a class is loaded by a lower-level loader (User-Defined ClassLoader). This loader first calls the upper-layer loader (AppClassLoader) for loading, the AppClassLoader will continue to be transferred to the upper-layer (ExtClassLoader) loader for loading until the BootstrapClassLoader. If the class path loaded by BootstrapClassLoader cannot find this class, it will be handed over to the next layer of the loader (ExtClassLoader) for loading. If this class cannot be found, it will be handed over to the next layer (AppClassLoader). Similarly, if the user-defined ClassLoader cannot find this class, the program will throw a ClassNotFoundError. The entire loading process is shown as follows:

(Picture referenced from: https://www.cnblogs.com/xing901022/p/4574961.html)

Tracking the source code of the class loading source code is as follows (the source code is simplified here). You can click the source code to view it:

Package java. lang. ClassLoader;
Import... protected Class <?> LoadClass (String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock (name) {// First, check whether this class has been loaded in the VM memory... main Problems with class cache !!! Class <?> C = findLoadedClass (name); if (c = null) {long t0 = System. nanoTime (); try {if (parent! = Null ){
// First load the c = parent with the last loader. loadClass (name, false);} else {c = findBootstrapClassOrNull (name);} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found // from the non-null parent class loader} if (c = null) {// call the findClass method implemented by this loader to load c = findClass (name) ;}}if (resolve) {resolveClass (c) ;}return c ;}}

In the source code, you can fully understand the process of parent-parent delegation. The most important three sentences of code have been marked:

FindLoadedClass (Find out whether the class cache has been loaded in the VM memory !!!)
Parent. loadClass (Let the previous loader Load)
FindClass (Call the findClass method implemented by this type of loader for loading.)


  
If you need a custom loader to load the class file in the specified path, you must inherit the ClassLoader and implement the findClass (String name) method. Example:
Package com. bkjia. utils; import java. io. byteArrayOutputStream; import java. io. fileInputStream; import java. io. IOException; import java. io. inputStream; public class ServiceClassLoader extends ClassLoader {private String classPath; public ServiceClassLoader (String classPath) {this. classPath = classPath;}/*** override the findClass method of the parent class. The loadClass of the parent Class calls this method */@ Override protected Class <?> FindClass (String name) throws ClassNotFoundException {Class <?> C = null; byte [] classData = getClassData (name); if (classData! = Null) {c = defineClass (name, classData, 0, classData. length);} else {throw new ClassNotFoundException ();} return c ;}
  
// Read the class file through the IO stream and convert it to the byte array private byte [] getClassData (String name) {String path = classPath + "/" + name. replace ('. ','/') + ". class "; InputStream iStream = null; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream (); try {iStream = new FileInputStream (path); byte [] buffer = new byte [1024]; int temp = 0; while (temp = iStream. read (buffer ))! =-1) {byteArrayOutputStream. write (buffer, 0, temp);} if (byteArrayOutputStream! = Null) {return byteArrayOutputStream. toByteArray () ;}} catch (Exception e) {e. printStackTrace () ;}finally {try {if (iStream! = Null) {iStream. close () ;}} catch (IOException e) {e. printStackTrace () ;}try {if (byteArrayOutputStream! = Null) {byteArrayOutputStream. close () ;}} catch (IOException e) {e. printStackTrace () ;}} return null ;}}

The code for using the class loader is as follows:

ServiceClassLoader serviceClassLoader = new ServiceClassLoader("c:\myclass");Czlass<?> c = ServiceClassLoader.loadClass("com.bkjia.service.Myclass");

If the sameServiceClassLoaderThe object is loaded to the same Class file multiple times. The Class object after each loading is the same! However, if different new custom ClassLoader loads the same Class file, different Class objects will be returned each time.

Note: The Class file to be loaded cannot be placed under the classpath directory and any subdirectories; otherwise, it will be preferentially loaded by AppClassLoader (this is because the parent-parent delegation mechanism is used for Class loading, at the same time, AppClassLoader can load all class files under classpath. Each time it is loaded by the same AppClassLoader, class cache problems may occur.

  This solves the class cache problem that occurs when the JVM class is loaded directly using reflection.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.