java-- heat load

Turn: https://www.cnblogs.com/niumoo/p/11756703.html

1. What is the thermal load

Thermal load is one that can make code changes without restarting the service takes effect, the heat load can significantly enhance the development and efficiency of debugging, it is based on the Java class loader to achieve, but due to the thermal load of insecurity, generally not used for formal production environment.

2. The difference between the heat load and hot deployment

First, regardless of the heat load or hot deployment, you can compile / deploy the project without restarting services, are based on the Java class loader implementations.

So both in the end what difference does it make?

On the deployment:

  • Hot deployment is the server is running redeployment project.
  • Heat load at runtime reload the class .

In terms of implementation principles:

  • Hot deployment is a direct re- load the entire application , consuming relatively high.
  • Heat load at runtime reload the class , will start a background thread constantly testing your class has changed.

On the usage scenarios:

  • More heat is deployed in a production environment use.
  • Thermal load is more in the development environment using the. Because online security issues will not use, difficult to monitor.

3. Load class five stages

Class life cycle

As you may have discovered, it is drawing a total of seven stages, rather than five. Because the map is complete life cycle of the class, if only to say that the class loading phase, then, in view of the final use (Using) and unloading (Unloading) is not included.

Briefly describe the five stages of class loading:

  1. Loading phase: find static storage class structure, loaded into the virtual machine, define data structures. Users can customize the class loader.

  2. Validation phase: to ensure that bytecode is safe and will not cause harm to ensure the security of virtual machines.

  3. Preparation phase: to determine the memory layout, determine the memory traversal, assigned an initial value (Note: the initial value, there are special circumstances).

  4. Parsing stage: the symbol becomes a direct reference.

  5. Initialization phase: The code calls the custom programs. Regulations and only five cases must be initialized.
    1. new (instantiate an object), getstatic (to get a class variable value, is excluded final modified, he values ​​into the constant pool in the compiler), putstatic (to the class variable assignment), will be when invokestatic (call static methods) initialization
    2. When calling subclass, we found that the parent has not been initialized, the parent class needs to be initialized immediately.
    3. The virtual machine is started, the main class user to be performed, the main class needs to be initialized immediately, as the main method.
    4. The method of using the package of the class java.lang.reflect reflecting call is initializes.
    5. When using a dynamic language support JDK 1.7, if a java.lang.invoke.MethodHandle instance final
      analytical results REF_getStatic, REF_putStatic, REF_invokeStatic way to handle, and this method handle
      the corresponding class not been initialized, you need to trigger its initialization.

It is noted that, classloading five stages, only the loading stage users can customize the processing and validation phase, the preparation phase, resolution phase, the initialization phase is treated with the JVM.

4. The thermal loading implementation class

4.1 realization of ideas

How can we write a manual like a hot load it? According to the above analysis, Java program at run time, the first class will be loaded into the JVM class files, and loading classes have five stages, only five stages loading phase the user can customize the process, so we If you can change the program code and recompile, let the process run can get real-time to the newly compiled class files, and then re-load, then theoretically you can achieve a simple  Java heat load .

So we can conclude that the realization of ideas:

  1. Implement your own class loader.
  2. To load thermal load classes from its own class loader.
  3. Do you want to continue in rotation heat load class class file updates.
  4. If an update is reloaded.

4.2 custom class loader

External JVM Java Virtual Machine design team to load into the implementation phase of the class (by fully qualified name to get a description of such class of binary byte stream). This allows the program to decide if the class to get information. And to achieve this loading operation code modules, we call it "class loader."

In Java, the class loader that is  java.lang.ClassLoader. So if we want to achieve their own class loader, you need to inherit  ClassLoader and then rewrite inside  findClassthe method, and because the class loader is  双亲委派模型achieved (it said. In addition to a top-level class loader addition, each must have a parent class loader loader, but when loaded, it will first ask the parent loader can load, if the parent can not load loader will try to load your own) so we also need to specify the parent Loader.

Finally, according to the incoming path of the class, the class code loading see below.

package net.codingme.box.classloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;

/**
 * <p>
 * Custom Java class loader to achieve thermal load Java classes
 *
 * @Author niujinpeng
 * @Date 2019/10/24 23:22
 */
public class MyClasslLoader extends ClassLoader {

    / ** to load the classpath Java class * / 
    Private String classpath;

    public MyClasslLoader(String classpath) {
        // 指定父加载器
        super(ClassLoader.getSystemClassLoader());
        this.classpath = classpath;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] data = this.loadClassData(name);
        return this.defineClass(name, data, 0, data.length);
    }

    /**
     * Content loading class files
     *
     * @param name
     * @Return 
     * / 
    Private  byte [] loadClassData (String name) {
         the try {
             // passed in a package with the name 
            name = name.replace (, "//" "." );
            InputStream the FileInputStream = new new the FileInputStream ( new new File (CLASSPATH + name + ".class" ));
             // define ByteArrayOutputStream 
            ByteArrayOutputStream BAOS = new new ByteArrayOutputStream ();
             int B = 0 ;
             the while ((B = InputStream.read ( ))! = -1 ) {
                baos.write(b);
            }
            inputStream.close();
            return baos.toByteArray();
        } catch (Exception e) {
            e.printStackTrace ();
        }
        return null;
    }
}

4.3 To define the type of thermal loading of the class

We assume that one of the methods (logic) at an interface (BaseManager.java) to heat load treatment.

First, define the interface information.

package net.codingme.box.classloader;

/**
 * <p>
 * To achieve this subclass interfaces, you need to dynamically update. That is, heat load
 *
 * @Author niujinpeng
 * @Date 2019/10/24 23:29
 */
public interface BaseManager {

    public void logic();
}

Write a class that implements this interface.

package net.codingme.box.classloader;

import java.time.LocalTime;

/**
 * <p>
 * BaseManager this subclass interface to achieve thermal loading function class.
 *
 * @Author niujinpeng
 * @Date 2019/10/24 23:30
 */
public class MyManager implements BaseManager {

    @Override
    public void logic() {
        System.out.println (LocalTime.now () + ": thermal loading Java classes" );
    }
}

Later we have to do is make this class can be customized by loading our MyClassLoader. Class thermal load should only be changed in the information class and then reloaded after recompilation. Therefore, in order not to repeat the significance of the load, we need to determine whether the class has been updated, so we need to record such information Modified class category, and the corresponding.

The compiler is used to record a class corresponding to a class modified a class loader to load the class and the last.

package net.codingme.box.classloader;

/**
 * <p>
 * Information package loading classes
 *
 * @Author niujinpeng
 * @Date 2019/10/24 23:32
 */
public class LoadInfo {

    / ** custom class loader * / 
    Private MyClasslLoader myClasslLoader;

    / ** record timestamps to load classes -> load time * / 
    Private  Long loadTime;

    / ** needs to be thermally loaded class * / 
    Private BaseManager Manager;

    public LoadInfo(MyClasslLoader myClasslLoader, long loadTime) {
        this.myClasslLoader = myClasslLoader;
        this.loadTime = loadTime;
    }

    public MyClasslLoader getMyClasslLoader() {
        return myClasslLoader;
    }

    public void setMyClasslLoader(MyClasslLoader myClasslLoader) {
        this.myClasslLoader = myClasslLoader;
    }

    public long getLoadTime() {
        return loadTime;
    }

    public void setLoadTime(long loadTime) {
        this.loadTime = loadTime;
    }

    public BaseManager getManager() {
        return manager;
    }

    public void setManager(BaseManager manager) {
        this.manager = manager;
    }
}

4.4 thermal loading to get class information

In the realization of ideas, we know in rotation check class file is not being updated, so each call to the thermal load of classes, we have to check whether the class is updated and then decide whether or not to reload. In order to facilitate this step of acquiring operation, the plant can use a simple package mode.

To note the need to load the class file to specify the full path, so CLASS_PATH class defines constants.

package net.codingme.box.classloader;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * Load manager of the factory
 *
 * @Author niujinpeng
 * @Date 2019/10/24 23:38
 */
public class ManagerFactory {

    / ** recording information loaded heat loads classes * / 
    Private  static  Final the Map <String, LoadInfo> = loadTimeMap new new the HashMap <> ();

    / ** CLASSPATH to load the class * / 
    public  static  Final String CLASS_PATH = "D: \\ \\ IdeaProjectMy Lab-target Notes \\ \\ \\ classes" ;

    / ** achieve full thermal load class name (package name + class name) * / 
    public  static  Final String MY_MANAGER = "net.codingme.box.classloader.MyManager" ;

    public static BaseManager getManager(String className) {
        The loadFile File = new new File (CLASS_PATH className.replaceAll + (. "\\", "/") + ".class" );
         // get the last modified time 
        Long the lastModified = loadFile.lastModified ();
        System.out.println ( "current of class time:" + lastModified);
         // loadTimeMap ClassName does not contain the information key to prove that this class is not loaded, to load into the JVM 
        IF (loadTimeMap.get (className) == null ) {
            load(className, lastModified);
        } // load the class timestamp changes, and we also want to reload this class to the JVM. 
        the else  IF (loadTimeMap.get (className) .getLoadTime ()! = the lastModified) {
            load(className, lastModified);
        }
        return loadTimeMap.get(className).getManager();
    }

    /**
     * Load class, cache to loadTimeMap
     * 
     * @param className
     * @param lastModified
     */
    private static void load(String className, long lastModified) {
        MyClasslLoader myClasslLoader = new MyClasslLoader(className);
        The loadClass class = null ;
         // load 
        the try {
            loadClass = myClasslLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace ();
        }

        BaseManager manager = newInstance(loadClass);
        LoadInfo loadInfo = new LoadInfo(myClasslLoader, lastModified);
        loadInfo.setManager(manager);
        loadTimeMap.put(className, loadInfo);
    }

    /**
     * To reflect the way to create a subclass of objects BaseManager
     * 
     * @param loadClass
     * @return
     */
    private static BaseManager newInstance(Class loadClass) {
        try {
            return (BaseManager)loadClass.getConstructor(new Class[] {}).newInstance(new Object[] {});
        } catch (InstantiationException e) {
            e.printStackTrace ();
        } catch (IllegalAccessException e) {
            e.printStackTrace ();
        } catch (InvocationTargetException e) {
            e.printStackTrace ();
        } catch (NoSuchMethodException e) {
            e.printStackTrace ();
        }
        return null;
    }
}

4.5 Thermal load test

Write directly to a continuous thread to detect the thermal load of classes has changed is not the need to reload, and then run the test can be.

package net.codingme.box.classloader;

/**
 * <p>
 *
 * Start a background thread, constantly testing whether you want to refresh to reload, to achieve a thermal load of classes
 * 
 * @Author niujinpeng
 * @Date 2019/10/24 23:53
 */
public class MsgHandle implements Runnable {
    @Override
    public void run() {
        while (true) {
            BaseManager manager = ManagerFactory.getManager(ManagerFactory.MY_MANAGER);
            manager.logic();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace ();
            }
        }
    }
}

The main thread:

package net.codingme.box.classloader;

public class ClassLoadTest {
    public static void main(String[] args) {
        new Thread(new MsgHandle()).start();
    }
}

All code has been ready for the last step, you can start testing. If you are using a Eclipse, started directly on the line; if it is IDEA, then you need to start DEBUG mode (IDEA heat loaded with certain restrictions).

After you start to see the console output continued:

00: 08: 13.018 : Hot Java class loader
 00: 08: 15.018: Hot Java class loader

At this time the contents of the output logic method we just change the next MyManager classes and save.

@Override
public void logic() {
     System.out.println (LocalTime.now () + ": thermal Java class loading ~~~~ Oh" );
}

You can see the console output has been automatically changed (IDEA after the change need to press CTRL + F9).

Code has been put Github: https://github.com/niumoo/lab-notes/

Guess you like

Origin www.cnblogs.com/jvStarBlog/p/11762754.html