欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 Java Virtual Machine-First part(●----●)

程序员文章站 2022-04-30 08:01:35
对Java的理解Note : 如果源码中出现有native非访问控制修饰符时,那么说明其调用了非java实现的代码库,此时可以通过该网站进行查阅native lib,由于oracle的jdk是部分闭源的,而openjdk是开源的,所以选择在openjdk看native libOverview文章目录对Java的理解OverviewExtensionCompile once, run anywhereGC (Garbage Collection)Extension平台无关性:编译一次,到处运行...

对Java的理解

Note : 如果源码中出现有native非访问控制修饰符时,那么说明其调用了非java实现的代码库,此时可以通过该网站进行查阅native lib,由于oracle的jdk是部分闭源的,而openjdk是开源的,所以选择在openjdk看native lib

Overview

Extension

  • 平台无关性:编译一次,到处运行
  • GC ( Garbege Collection ):
  • 语言特性:lambda表达式,反射,泛型:
  • 面向对象:封装,继承,多态:
  • 类库:
  • 异常处理:

Compile once, run anywhere

  • 利用javac对.java文件进行compile,之后产生.class文件。.class文件包含了??? 。之后我们可以通过javap,也就是jdk自带的反汇编器,来查看.class文件的内容。

    wong@MacBook-Pro Desktop % javap -c Test.class 
    Compiled from "Test.java"
    public class Test {
      public Test();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."<init>":()V
           4: return
    
      public static void main(java.lang.String[]);
        Code:
           0: iconst_0
           1: istore_1
           2: iconst_0
           3: istore_2
           4: iinc          1, 1
           7: iinc          2, 1
          10: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
          13: iload_1
          14: invokevirtual #13                 // Method java/io/PrintStream.println:(I)V
          17: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
          20: iload_2
          21: invokevirtual #13                 // Method java/io/PrintStream.println:(I)V
          24: return
    }
    

    Java源码首先被编译成java字节码,再由不同平台的JVM进行解析。java语言在不同平台上运行不需要进行重新编译,java虚拟机在执行字节码的时候,再将字节码转换成平台对应的机器指令。

  • JVM如何加载.class文件
    荐
                                                        Java Virtual Machine-First part(●----●)

    上图是JVM的架构图。

    • Class Loader : 依据特定格式,加载class文件到内存
    • Execution Engine : 对命令进行解析
    • Native Interface : 融合不同开发语言的原生库为java所用
    • Runtime Data Area : JVM内存空间结构模型
  • Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的方法和属性;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息和动态调用对象方法的功能成为Java的反射机制

    Class rb = Class.forName("code1.Robot");
    		Robot r = (Robot)rb.newInstance();
    		System.out.println("Class name is " + rb.getName());
    		Method getHello = rb.getDeclaredMethod("throwHello", String.class);
    		getHello.setAccessible(true);
    		Object str = getHello.invoke(r, "Bob");
    		System.out.println("The name is " + str);
    		Field name = rb.getDeclaredField("name");
    		name.setAccessible(true);
    		name.set(r, "Obama");
    		Method sayHi = rb.getMethod("sayHi", String.class);
    		sayHi.invoke(r, "What");
    
  • 类从编译到执行的过程

    • 编译器将.java源文件编译为.class字节码文件
    • ClassLoader将字节码转换为JVM中的Class对象
    • 而从字节码文件传入的数据格式是以byte[]形式传入的
    • 之后JVM通过Class对象实例化为Robot对象
  • ClassLoader在Java中有着非常重要的地位。它主要工作在Class装载阶段,其主要作用是从系统外部获得Class字节码数据流。它是java的核心组件,所有的class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的字节码数据流装载进系统,然后交给Java虚拟机进行连接,初始化等操作。

    • BootStrapClassLoader : C++编写,加载核心库java.*
    • ExtClassLoader : Java编写, 加载扩展库javax.*
    • AppClassLoader : Java编写, 加载程序所在目录
    • 自定义ClassLoader : Java编写, 定制化加载
    public class MyClassLoader extends ClassLoader {
    
    	private String path;
    	
    	private String classLoaderName;
    	
    	public MyClassLoader(String path, String classLoaderName) {
    		
    		this.path = path;
    		this.classLoaderName = classLoaderName;
    	}
    	
    	// Find Class File
    	@SuppressWarnings("deprecation")
    	@Override
    	public Class findClass(String name) {
    		
    		byte[] b = loadClassData(name);
    		return defineClass(b, 0, b.length);
    	}
    
    	// Load Class File
    	private byte[] loadClassData(String name) {
    		name = path + name + ".class";
    		InputStream in = null;
    		ByteArrayOutputStream out = null;
    		try {
    			in = new FileInputStream(new File(name));
    			out = new ByteArrayOutputStream();
    			int i = 0;
    			while( (i = in.read()) != -1) {
    				out.write(i);
    			}
    		} catch (Exception e) {
    			// TODO: handle exception
    			e.printStackTrace();
    		} finally {
    			try {
    				out.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			try {
    				in.close();
    			} catch (IOException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    		// TODO Auto-generated method stub
    		return out.toByteArray();
    	}
    }
    
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    		MyClassLoader mc = new MyClassLoader("/Users/wong/", "wali.class");
    		Class c = mc.loadClass("Wali");
    		System.out.println(c.getClassLoader());
    		c.newInstance();
    	}
    
    • ASM & 字节码增强技术 & AOP的实现
  • 类加载器的双亲委派机制

荐
                                                        Java Virtual Machine-First part(●----●)

  • 为何要使用双亲委派机制?因为避免同一个字节码文件加载多次,避免占用多余的内存空间

  • 类的加载方式

    • 隐式加载:new
    • 显示加载:loadClass, forName等
    • loadClass与forName的区别:

荐
                                                        Java Virtual Machine-First part(●----●)

GC (Garbage Collection)

酝酿中…

本文地址:https://blog.csdn.net/weixin_41741302/article/details/107335641