JVM入门

JVM

一、JVM概述

架构师每天在想什么/h2>
  • 如何让系统更快/li>
  • 如何避免系统出现瓶颈/li>

知乎有条帖子:应该如何看待招聘,年薪直通50万/strong>

  1. 性能优化,重构,保证平台性能和稳定性
  2. 根据业务场景和需求,决定技术方向,技术选型
  3. 能够独立架构与设计海量数据下的高并发分布式解决方案
  4. 核心功能的架构与代码编写
  5. 分析系统瓶颈,解决各种疑难杂症,性能调优等

为什么要学习JVM

  • 面试的需要(BATJ、TMD、PKQ等面试都爱问)
  • 中高级程序员必备技能
    • 项目调优的需求
  • 极客精神
    • 比如:垃圾回收算法、JIT(及时编译器)、底层原理

JVM是一种虚拟机设备的规范,是虚构出来的一台机器

  • 标准:The Java Virtual Machine Specification
  • 在Oracle官 https://docs.oracle.com/javase/specs/index.html 可以免费下载各个JDK版本的JVM规范要求

各个大厂都有自己的JVM的实现

  1. HotSpot是Oracle官方实现
  2. J9是IBM的实现
  3. Microsoft JVM是微软的实现
  4. Harmony是Apache的实现
  5. Azul Zing是第三方公司Azul Systems开发的商业收费虚拟机,目前银行在用。它的垃圾回收器PGC、C4停顿时间可控制在10ms内。Oracle最新的JDK12中的ZGC及Shenandoah垃圾回收器就是参考的这款,但效果还远不如它。(书P17)

如何查看自己电脑使用的是哪一款JVM/h3>

Win + R -> cmd -> java -version

JVM整体架构

类加载器子系统作用

  1. 类加载器只负责字节码文件的加载

  2. 字节码文件能否运行取决于执行引擎

  3. 加载的类信息存放在称为方法区的内存空间。除了类信息,方法区中还存放运行时常量池信息,可能还包括字符串字面量和数字常量

类的加载过程

完整的流程图如下所示:

准备(Prepare)

  1. 为类变量(static变量)分配内存并且设置该类变量的默认初始值,即零值
  2. 这里不包含用final修饰的static,因为final在编译阶段就会分配好了默认值,准备阶段会按照程序员给的值显式进行初始化
  3. **注意:**这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中

举例
代码:类变量a在准备阶段会赋初始值,但不是1,而是0,在初始化阶段会被赋值为 1

  • 我们尝试获取BootstrapClassLoader,获取到的值为 null ,这并不代表BootstrapClassLoader加载器不存在,因为启动类加载器用的C/C++ 语言,我们获取不到
  • 两次获取应用类加载器的值都相同:sun.misc.Launcher$AppClassLoader@18b4aac2 ,这说明应用类加载器是全局唯一的

虚拟机自带的加载器

启动类加载器

启动类加载器(引导类加载器,Bootstrap ClassLoader)

  1. 这个类加载使用C/C++语言实现的,嵌套在JVM内部
  2. 它用来加载Java的核心库(JAVA_HOME/jre/lib/rt.jar、resources.jar或sun.boot.class.path路径下的内容),用于提供JVM自身需要的类
  3. 并不继承自java.lang.ClassLoader,没有父加载器
  4. 加载扩展类和应用程序类加载器,并作为他们的父类加载器
  5. 出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类

扩展类加载器

扩展类加载器(Extension ClassLoader)

  1. Java语言编写,由sun.misc.Launcher$ExtClassLoader实现
  2. 派生于ClassLoader类
  3. 父类加载器为启动类加载器
  4. 从java.ext.dirs系统属性所指定的目录中加载类库,或从JDK的安装目录的jre/lib/ext子目录(扩展目录)下加载类库。如果用户创建的JAR放在此目录下,也会自动由扩展类加载器加载

应用程序类加载器

应用程序类加载器(也称为系统类加载器,AppClassLoader)

  1. Java语言编写,由sun.misc.Launchers$AppClassLoader实现
  2. 派生于ClassLoader类
  3. 父类加载器为扩展类加载器
  4. 它负责加载环境变量classpath或系统属性java.class.path指定路径下的类库
  5. 该类加载是程序中默认的类加载器,一般来说,Java应用的类都是由它来完成加载
  6. 通过classLoader.getSystemclassLoader()方法可以获取到该类加载器

输出结果

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月11日
下一篇 2021年1月11日

相关推荐