《剑指Java面试-Offer直通车》--Java底层知识JVM

本文详细探讨了Java的平台无关性实现、JVM加载.class文件的原理、反射机制、类加载器的工作原理和双亲委派机制,以及loadClass与forName的区别。此外,还介绍了Java内存模型中的重要概念,如程序计数器、虚拟机栈、本地方法栈、元空间和Java堆。通过对这些核心知识点的解析,帮助读者深入理解Java运行时的内存管理和类加载过程。
摘要由CSDN通过智能技术生成

目录

一、平台无关性如何实现?

二、JVM如何加载.class文件?

Java虚拟机

JVM架构

三、反射

四、ClassLoader类加载器

ClassLoader的作用

ClassLoader的种类

自定义ClassLoader的实现

五、类加载器的双亲委派机制

六、loadClass和forName的区别

类的加载方式

类的装载过程

loadClass和forName的区别

七、Java内存模型

内存简介

JVM内存模型--JDK8

从线程的角度

        程序计数器(Program Counter Register)

        Java虚拟机栈(Stack)

        本地方法栈(Native Method Stack)

        元空间(MetaSpace)

        Java堆(Heap)

从存储的角度

        JVM三大性能调优参数-Xms、-Xmx、-Xss的含义

        Java内存模型中堆和栈的区别--内存分配策略

OOM

推荐资料


一、平台无关性如何实现?

compile once,run anywhere.

编译:javac指令,将源码编译成字节码,生成.class文件(字节码文件)

运行:java指令,JVM解析.class文件,加载进内存,转化成特定平台的执行指令

 

二、JVM如何加载.class文件?

  • Java虚拟机

虚拟机是一种抽象化的计算机,在实际计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM屏蔽底层操作系统平台的不同,并且减少基于原生语言开发的复杂性。只要虚拟机厂商在特定操作系统上实现了虚拟机,定义如何将字节码解析成本操作系统可执行的二进制码(机器码),Java便能实现跨越各种平台。JVM最值得我们学习的两点是JVM内存结构模型和GC。JVM是内存中的虚拟机,JVM的存储就是内存,类、变量、方法都在内存中。

参考:字节码和机器码的区别

  • JVM架构

ClassLoader加载javac编译好的.class文件到内存,不是任意的.class文件都能加载,ClassLoader加载的文件有格式要求。ClassLoader只管加载,只要符合格式要求就能加载,能不能运行由Execution Engine负责;Execution Engine负责对命令进行解析,解析完之后提交到操作系统执行;Native Interface融合不同编程语言为Java所用。Java执行性能绝大多数情况下没有C或者C++高,主流JVM也是基于C++实现的,涉及到一些较高性能的运算时,需要在Java直接调用它们。另外,本着不重复调用的原则,某个库如果已经用到别的语言开发,就不需要再开发一套,而是Java直接对这些库进行调用,为了满足上述要求,JVM在内存中开辟了一块区域处理标记为Native的代码,具体做法是Native Method中登记Native方法,在Execution执行时加载Native方法;程序被加载到Runtime Data Area这里运行。

 

三、反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能够调用它的方法和属性。这种动态获取信息和动态调用方法的功能称为Java语言的反射机制。

eg:

package com.reflect;

public class Person {
    private String name;
    public void sayHi(String str){
        System.out.println(str+name);
    }
    private String throwHello(String name){
        return "hello,"+name;
    }
}
package com.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectSample {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class cls=Class.forName("com.reflect.Person");
        System.out.println("类名:"+cls.getName());
        Person person=(Person)cls.newInstance();
        /**private方法的调用*/
        //getDeclaredMethod方法的第一个参数是String类型的方法名,第二个参数是方法传入的参数类型.class
        //getDeclaredMethod能获取所有修饰符修饰的方法,不能获取继承的方法和实现的接口的方法
        Method  throwHello=cls.getDeclaredMethod("throwHello",String.class);
        //私有的需要设置为true
        throwHello.setAccessible(true);
        //invoke方法的第一个参数是对象的实例,第二个参数是上述方法传入的参数
        Object obj=throwHello.invoke(person,"Zhansan");
        System.out.println("throwHello的结果:"+obj);

        /**public方法的调用*/
        //getMethod只能获取public方法,还能获取继承的方法和实现的接口的方法
        Method sayHi=cls.getMethod("sayHi",String.class);
        sayHi.invoke(person,"hi,");

        /**获取private属性*/
        Field name=cls.getDeclaredField("name");
        name.setAccessible(true);
        name.set(person,"lisi");
        sayHi.invoke(person,"hi,");
    }
}

执行结果为:

类名:com.reflect.Person
throwHello的结果:hello,Zhansan
hi,null
hi,lisi

反射是将Java类中的各种成分映射成一个个Java对象:Field、Method、Class...

类从编译到执行的过程:1)编译器将Person.java源文件编译为Person.class字节码文件;2)ClassLoader将字节码转换为JVM中的Class<Person>对象(类对象、Class对象,不是new A();之类的对象);3)JVM利用Class<Person>对象实例化为Person对象。

参考:Java中的Class类Java中的java.lang.Class API 详解

 

四、ClassLoader类加载器

ClassLoader是一个抽象类,里面最重要的方法是loadClass。

  • ClassLoader的作用

ClassLoader在Java中有着非常重要的作用,主要工作在Class装载的加载阶段,主要作用是从系统外部获得Class二进制数据流。它是Java的核心组件,所有的Class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载进系统,然后交给Java虚拟机进行连接、初始化等操作。

  • ClassLoader的种类

1)BootStrapClassLoader:C++编写,加载核心库java.*

2)ExtClassLoader:Java编写,加载扩展库javax.*  (在IDEA导航项Navigate下的Class中搜索ExtClassLoader可以看到ExtClassLoader类的源代码,AppClassLoader同理。BootStrapClassLoader是C++编写的,只能去JVM源码中看)

3)AppClassLoader:Java编写,加载程序所在目录(classpath)

4)自定义ClassLoader:Java编写,定制化加载

  • 自定义ClassLoader的实现

关键函数

1)findClass:寻找class文件,包括读进二进制流,处理,返回一个Class对象

    protected Class<?> findClass(String name) throws ClassNotFoundException {
        throw new ClassNotFoundException(name);
    }

2) defineClass:定义一个类,字节码以byte[]数组形式传递进

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值