JVM学习笔记-面试知识点

本文围绕JVM展开,介绍了JVM加载.class文件的过程、类从编译到执行的流程,阐述了ClassLoader的种类和类的加载方式、装载过程,对比了loadClass和forName的区别。还详细讲解了JVM内存模型-JDK8各部分,如程序计数器、虚拟机栈等,以及JVM三大性能调优参数含义和堆与栈的区别。

JVM如何加载.class文件

JVM虚拟机

在这里插入图片描述
Class Loader:以特定格式,加载class文件到内存

Execution Engine:对命令进行解析

Native Interface:融合不同开发语言的原生库为java所用

Runtime Data Area:JVM内存空间结构模型

类从编译到执行的过程

编译器将java源文件编译成class字节码文件

ClassLoader将字节码转换为JVM中的Class对象

JVM利用Class对象实例化为实例对象

ClassLoader

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

ClassLoader的种类

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

  • ExtClassLoader:Java编写,加载扩展库javax.*

  • AppClassLoader:Java编写,加载程序所在目录

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

类的加载方式

隐式加载:new

显式加载:loadClass,forName等

类的装载过程

  1. 加载: 通过ClassLoader加载class文件字节码,生成Class对象
  2. 链接:
    • 校验:检查加载的class的正确性和安全性
    • 准备:为类变量分配存储空间并设置类变量初始值
    • 解析:JVM将常量池内的符号引用转换为直接引用
  3. 初始化:执行类变量赋值和静态代码块

loadClass和forName的区别

Class.forName得到的class是已经初始化完成的

ClassLoader.loadClass得到的class是还没有链接的

JVM内存模型-JDK8

在这里插入图片描述

  • 线程私有:程序计数器、虚拟机栈、本地方法栈
  • 线程共享:MetaSpace、Java堆
程序计数器
  • 当前线程所执行的字节码行号指示器(逻辑)
  • 改变计数器的值来选取下一条需要执行的字节码指令
  • 和线程是一对一的关系,即“线程私有”
  • 对Java方法计数,如果是Native方法则计数器值为Undefined
  • 不会发生内存泄漏
Java虚拟机栈(Stack)

在这里插入图片描述

  • Java方法执行的内存模型
  • 包含多个栈帧
局部变量表和操作数栈
  • 局部变量表:包含方法执行过程中的所有变量
  • 操作数栈:入栈、出栈、复制、交换、产生消费变量
递归为什么会引发java.lang.StackOverflowError异常

递归过深,栈帧数超过虚拟栈深度

本地方法栈

与虚拟机栈相似,主要作用于标注了native的方法

元空间(Metaspace):

存储已被虚拟机加载的类信息。随着JDK8的到来,JVM不再有方法区(PermGen),原方法区存储的信息被分成两部分:

1、虚拟机加载的类信息,被移动到元空间。

2、运行时常量池,被移动到了堆中 (静态成员变量) 。

MetaSpace(元空间)相比PermGen(永久代)的优势

元数据区取代了1.7版本及以前的永久代。元数据区和永久代本质上都是方法区的实现。方法区存放虚拟机加载的类信息,静态变量,常量等数据。

  • 字符串常量池存在永久代中,容易出现性能问题和内存溢出
  • 类和方法的信息大小难以确定,给永久代的大小指定带来困难
  • 永久代会给GC带来不必要的复杂性
  • 方便HotSpot与其他JVM如 Jrockit的集成
Java堆(Heap)
  • 对象实例的分配区域
  • GC管理的主要区域
直接内存(没有在上图体现出来)

jdk1.4引入了NIO,它可以使用Native函数库直接分配堆外内存。

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

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

一般Xms和Xmx设置为一样的值,因为扩容时会发生内存抖动。

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

  • 静态存储:编译时确定每个数据目标在运行时的存储空间需求
  • 栈式存储:数据区需求在编译时未知,运行时模块入口前确定
  • 堆式存储:编译时或运行时模块入口都无法确定,动态分配

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

  • 管理方式:栈自动释放,堆需要GC
  • 空间大小:栈比对小
  • 碎片相关:栈产生的碎片远小于堆
  • 分配方式:栈支持静态和动态分配,而堆仅支持动态分配
  • 效率:栈的效率比堆高
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值