• JVM面试题


    谈谈对Java的理解

    • 平台无关性
    • GC
    • 语言特性(泛型,反射,lambda等)
    • 面向对象
    • 类库
    • 异常处理

    Java的平台无关性

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

    JVM如何加载.class文件

    JVM架构图

    • Class Loader:根据特定的格式,加载class文件到内存
    • Execution Engine:对命令进行解析
    • Native Interface:融合不同开发语言的原生库为Java所用
    • Runtime Data Area:JVM内存空间模型

    谈谈反射

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

    ClassLoader的种类

    • BootStrapClassLoader:C++编写,加载核心库java.*
    • ExtClassLoader:java编写,加载扩展库javax.*
    • AppClassLoader:java编写,加载程序所在目录(项目中的src)
    • 自定义ClassLoader:java编写,定制化加载

    双亲委派机制

    参考的博客

    当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。

    作用

    1. 防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。

    2. 保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

    谈谈ClassLoader

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

    类加载的方式

    • 隐式加载:new
    • 显式加载:loadClass,forName

    类的装载过程

    loadClass和forName的区别

    • 使用Class.forName(className)装载class会对相应的类进行初始化,即上图类的装载过程的第三步
    • 使用ClassLoader.loadClass(className)装载class,则只会进行上图的第一步,不会进行链接

    总结

    ​ 一般情况下,这两个方法效果一样,都能装载Class。但如果程序依赖于Class是否被初始化,就必须用Class.forName(className)了。

    ​ 如:jdbc中的Driver注册时只能用Class.forName(className)

    因为,Driver在static块中会注册自己到java.sql.DriverManager。而static块就是在Class的初始化中被执行。所以这个地方就只能用Class.forName(className)。

    JVM内存模型

    线程私有部分:程序计数器、虚拟机栈、本地方法栈

    • 程序计数器

      • 当前线程所执行的字节码行号指示器(逻辑)(多线程时,上下文切换,依靠程序计数器来恢复正确的执行位置)
      • 改变计数器的值来选取下一条需要执行的字节码指令
      • 和线程是一对一的关系即“线程私有”
      • 对Java方法计数,如果是Native方法则计数器值为Undefined
      • 不会发生内存泄漏
    • 虚拟机栈

      • Java方法执行的内存模型
      • 包含多个栈帧
      • 局部变量表和操作数栈
        • 局部变量表:包含方法执行过程中的所有变量
        • 操作数栈:入栈、出栈、复制、交换、产生消费变量(用来执行加减乘除等操作)
    • 本地方法栈

      • 本地方法栈和java虚拟机栈十分相似,差别不过是java虚拟机栈是为了java虚拟机执行字节码所服务,而本地方法栈则是为了执行native方法所服务的,所以本地方法也是一个私有的内存区域,也是后进先出栈,作用是支撑native方法的调用,执行和退出与java虚拟机栈一样也会出现以上两种异常。

    线程共享部分:共享部分为:MetaSpace(元空间),Java堆

    • 元空间(MetaSpace)与永久代(PermGen)的区别:(用元空间代替永久代)

      • 元空间使用的是本地内存,而永久代使用的是jvm的内存
      • 字符串常量池存在永久代中,容易出现性能问题和内存溢出
      • 类和方法的信息大小难以确定,给永久代的大小指定带来困难
      • 永久代会为GC带来不必要的复杂性
    • Java堆(Heap),在虚拟机启动时创建

      • 对象实例的分配区域(Java堆的唯一目的)
      • GC管理的主要区域

    JVM三大性能调优参数

    • -Xss:规定了每个线程虚拟机栈的大小
    • -Xms:堆的初始值
    • -Xmx:堆能达到的最大值

    Java内存模型中堆和栈的区别

    • 联系:引用对象、数组时,栈里定义变量保存堆中目标的首地址

    • 区别

      • 管理方式:栈自动释放,堆需要GC
      • 空间大小:栈比堆小
      • 内存碎片相关:栈产生的碎片远小于堆
      • 分配方式:栈支持静态和动态分配,而堆仅支持动态分配
      • 效率:栈的效率比堆高
  • 相关阅读:
    go语言从零学起(三) -- chat实现的思考
    go语言从零学起(二)--list循环删除元素(转载)
    go语言从零学起(一) -- 文档教程篇
    Spring框架事务支持模型的优势
    Thymeleaf
    社保到底是多交好,还是少交好?
    使用静态工厂方法而不是构造器
    EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf
    MySQL存储过程
    MySQL常用功能语句分类总结
  • 原文地址:https://www.cnblogs.com/shouyaya/p/13523714.html
Copyright © 2020-2023  润新知