Java教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java vs. C++
- JVM - Java虚拟机
- Java - JDK vs JRE vs JVM
- Java - Hello World程序
- Java - 环境搭建
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期与时间
Java控制语句
- Java - 循环控制
- Java - 决策机制
- Java - if-else
- Java - switch
- Java - for循环
- Java - 增强for循环
- Java - while循环
- Java - do-while循环
- Java - break
- Java - continue
面向对象编程
- Java - OOPs概念
- Java - 对象与类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造器
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态
- Java - 方法重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造器
- Java - 枚举字符串
Java内置类
Java文件处理
Java错误与异常
- Java - 异常
- Java - try-catch块
- Java - try-with-resources
- Java - 多重catch块
- Java - 嵌套try块
- Java - finally块
- Java - throw异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 线程连接
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java同步
Java网络编程
- Java - 网络编程
- Java - Socket编程
- Java - URL处理
- Java - URL类
- Java - URLConnection类
- Java - HttpURLConnection类
- Java - Socket类
- Java - 泛型
Java集合
Java接口
Java数据结构
Java集合算法
高级Java
- Java - 命令行参数
- Java - Lambda表达式
- Java - 发送邮件
- Java - Applet基础
- Java - Javadoc注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多发行版Jar文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64编码解码
- Java - switch表达式
- Java - Teeing Collectors
- Java - 微基准测试
- Java - 文本块
- Java - 动态CDS归档
- Java - Z垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 简洁数字格式化
- Java - 垃圾回收
- Java - JIT编译器
Java杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - Process API改进
- Java - Stream API改进
- Java - 增强@Deprecated注解
- Java - CompletableFuture API改进
- Java - 流
- Java - 日期时间API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java APIs与框架
Java类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
Java实用资源
JVM(Java虚拟机)架构
什么是JVM(Java虚拟机)?
JVM(Java虚拟机)是一个虚拟机,一个抽象的计算机,拥有自己的指令集架构(ISA)、内存、堆栈、堆等。它运行在主机操作系统上,并向其提出资源需求。
JVM(Java虚拟机)是一个规范,只要符合规范,就可以有不同的实现。规范可以在以下链接中找到:https://docs.oracle.com
Oracle有自己的JVM实现(称为HotSpot JVM),IBM也有自己的(例如J9 JVM)。
规范中定义的操作如下所示(来源 - Oracle JVM规范)
- “.class”文件格式
- 数据类型
- 基本类型和值
- 引用类型和值
- 运行时数据区域
- 栈帧
- 对象的表示
- 浮点运算
- 特殊方法
- 异常
- 指令集摘要
- 类库
- 公共设计,私有实现
JVM(Java虚拟机)架构
HotSpot JVM 3 的架构如下所示:
执行引擎包含垃圾收集器和JIT编译器。JVM有两种类型:客户端和服务器端。两者共享相同的运行时代码,但使用的JIT不同。稍后我们将详细了解这一点。用户可以通过指定JVM标志 -client 或 -server 来控制使用哪种类型。服务器端JVM是为服务器上长期运行的Java应用程序设计的。
JVM有32位和64位版本。用户可以使用VM参数中的-d32或-d64来指定要使用的版本。32位版本最多只能寻址4G内存。对于在内存中维护大型数据集的关键应用程序,64位版本可以满足这一需求。
JVM(Java虚拟机)架构的组成部分
以下是JVM(Java虚拟机)架构的主要组成部分:
1. 类加载器
JVM以动态的方式管理加载、链接和初始化类和接口的过程。在加载过程中,JVM查找类的二进制表示并创建它。
在链接过程中,加载的类被组合到JVM的运行时状态中,以便它们可以在初始化阶段执行。JVM基本上使用存储在类的方法区域的运行时常量池中的符号表来进行链接过程。初始化包括实际执行链接的类。
以下是类加载器的类型:
- 引导类加载器:此类加载器位于类加载器层次结构的顶部。它加载JRE的lib目录中的标准JDK类。
- 扩展类加载器:此类加载器位于类加载器层次结构的中间,是引导类加载器的直接子类,加载JRE的lib\ext目录中的类。
- 应用程序类加载器:此类加载器位于类加载器层次结构的底部,是应用程序类加载器的直接子类。它加载由CLASSPATH ENV变量指定的jar和类。
2. 链接和初始化
链接过程包含以下三个步骤:
- 验证 - 这由字节码验证器完成,以确保生成的.class文件(字节码)有效。如果不是,则抛出错误,链接过程停止。
- 准备 - 为类的所有静态变量分配内存,并使用默认值初始化它们。
- 解析 - 所有符号内存引用都替换为原始引用。为此,使用了类的方法区域中运行时常量内存中的符号表。
初始化是类加载过程的最后阶段。静态变量被赋予原始值,并执行静态块。
3. 运行时数据区域
JVM规范定义了程序执行期间需要的某些运行时数据区域。其中一些在JVM启动时创建。其他区域是特定于线程的,只有在创建线程时才创建(并在线程销毁时销毁)。这些列在下面:
PC(程序计数器)寄存器
它特定于每个线程,并包含线程当前正在执行的JVM指令的地址。
栈
它特定于每个线程,在方法调用期间存储参数、局部变量和返回地址。如果线程请求的堆栈空间超过允许的范围,则可能会发生StackOverflowError。如果堆栈是动态可扩展的,它仍然可以抛出OutOfMemoryError。
堆
它被所有线程共享,包含在运行时创建的对象、类的元数据、数组等。它在 JVM 启动时创建,在 JVM 关闭时销毁。您可以使用某些标志控制 JVM 向操作系统请求的堆大小(稍后详细介绍)。需要注意的是,不要请求过少或过多的内存,因为它会严重影响性能。此外,GC 管理此空间,并持续删除不再使用的对象以释放空间。
方法区
这个运行时区域对所有线程都是通用的,在 JVM 启动时创建。它存储每个类的结构,例如常量池(稍后详细介绍)、构造函数和方法的代码、方法数据等。《Java 语言规范》(JLS) 没有规定此区域是否需要进行垃圾回收,因此,JVM 的实现可以选择忽略 GC。此外,它可以根据应用程序的需求进行扩展或不扩展。JLS 对此没有任何强制规定。
运行时常量池
JVM 维护一个每个类/每个类型的、用作符号表(它的众多角色之一)的数据结构,用于链接已加载的类。
本地方法栈
当线程调用本地方法时,它会进入一个新的环境,在这个环境中,Java 虚拟机的结构和安全限制不再限制它的自由。本地方法可能会访问虚拟机的运行时数据区域(取决于本地方法接口),但也可能执行任何其他操作。
4. 执行引擎
执行引擎负责执行字节码,它包含三个不同的组件
垃圾回收
JVM 管理 Java 中对象的整个生命周期。一旦创建了对象,开发人员就不必再担心它。如果对象变成不再使用(即,不再有对它的引用),它将由 GC 使用多种算法(串行 GC、CMS、G1 等)从堆中移除。
另请阅读: Java 中的垃圾回收
在 GC 过程中,对象会在内存中移动。因此,在该过程进行期间,这些对象不可用。整个应用程序必须在该过程持续时间内停止。此类暂停称为“停止世界”暂停,并且开销巨大。GC 算法的主要目标是减少此时间。
解释器
解释器解释字节码。它解释代码的速度很快,但执行速度很慢。
JIT 编译器
JIT 代表 Just-In-Time(即时)。JIT 编译器是 Java 运行时环境的主要部分,它在运行时将字节码编译为机器码。
5. Java 本地接口 (JNI)
Java 本地接口 (JNI) 与对执行必不可少的本地方法库交互。
6. 本地方法库
本地方法库是 C 和 C++ 库(本地库)的集合,对执行必不可少。