程序计数器
程序计数器介绍程序计数器(Program Counter Register)中的Register的命名源于CPU的寄存器,寄存器存储相关指令的现场信息。CPU只有把数据装载到寄存器才能够运行。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。
程序计数器是一块很小的内存空间,几乎可以忽略不记,它也是运行速度最快的存储区域。
在JVM规范中,每 个线程都有它自己的程序计数器,它是线程私有的,生命周期与线程的生命周期保持一致。
任何时间的一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者如果是在执行native方法,则是未指定值(undefned)。
它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。并且字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
它是唯一一个在Java虚拟机规范中没有规定任何outotMemoryError情况的区域。
作用PC寄存器用来存储指向下一条指令的地址,即将要执行的指令代码,并由执行引擎读取下一条指令。 ...
运行时数据区概述
运行时数据区概述运行时数据区,见下图,它是在类加载完成后的阶段。
当我们通过前面的:类的加载-> 验证 -> 准备 -> 解析 -> 初始化 , 这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区。内存
内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行,JVM规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的JVM对于内存的划分方式和管理机制存在着部分差异。
而我们通过磁盘或者网络IO得到的数据,都需要先加载到内存中,然后CPU从内存中获取数据进行读取,也就是说内存充当了CPU和磁盘之间的桥梁。
运行时数据区的完整图
Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。
灰色的为单独线程私有的,红色的为多个线程共享的。即:
每个线程:独立包括程序计数器、栈、本地栈。
线程间共享:堆 ...
类加载子系统
类加载器子系统
类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。
ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。
加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射)。
Java中类的加载过程例如下面的一段简单的代码:
12345public class HelloWorld { public static void main(String[] args) { System.out.println("我已经被加载啦"); }}
它的加载过程是怎么样的呢?完整的流程如下图所示:加载阶段
通过一个类的全限定名获取定义此类的二进制字节流
将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
在内存中生成一个代表这个类的java.lang. ...
JVM基本架构及生命周期
JVM基本介绍Java虚拟机是一台执行Java字节码的虚拟计算机,它拥有独立的运行机制,其运行的Java字节码也未必由Java语言编译而成。JVM平台的各种语言可以共享Java虚拟机带来的跨平台性、优秀的垃圾回器,以及可靠的即时编译器。
Java技术的核心就是Java虚拟机(JVM,Java Virtual Machine),因为所有的Java程序都运行在Java虚拟机内部。
Java虚拟机就是二进制字节码的运行环境,负责装载字节码到其内部,解释/编译为对应平台上的机器指令执行。每一条Java指令,Java虚拟机规范中都有详细定义,如怎么取操作数,怎么处理操作数,处理结果放在哪里。
特点:
一次编译,到处运行
自动内存管理
自动垃圾回收功能
JVM整体架构
HotSpot VM是目前市面上高性能虚拟机的代表作之一。
它采用解释器与即时编译器并存的架构。
执行引擎包含三部分:解释器,及时编译器,垃圾回收器。
Java代码执行流程
JVM 架构模型
Java编译器输入的指令流基本上是一种基于栈的指令集架构,另外一种指令集架构则是基于寄存器的指令集架构。具体来说:这两种架构之 ...
Java关键字
final 关键字final 关键字,意思是最终的、不可修改的,用来修饰类、方法和变量,具有以下特点:
final 修饰的类不能被继承,final 类中的所有成员方法都会被隐式的指定为 final 方法;
final 修饰的方法不能被重写;
final 修饰的变量是常量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能让其指向另一个对象。
说明:使用 final 方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的 Java 实现版本中,会将 final 方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的 Java 版本已经不需要使用 final 方法进行这些优化了)。类中所有的 private 方法都隐式地指定为 final。
static 关键字static 关键字主要有以下四种使用场景:
修饰成员变量和成员方法: 被 static 修饰的成员属于类,不属于这个类的某个对象,被类中所有对象共享,可以通过类名调用。被 static 声明的成员 ...
反射机制
何为反射?反射是动态获取信息以及动态调用对象方法的一种机制。它赋予了我们在运行时分析类以及执行类中方法的能力。通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。
反射的应用场景了解么?Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。这些框架中也大量使用了动态代理,而动态代理的实现也依赖反射。
比如下面是通过 JDK 实现动态代理的示例代码,其中就使用了反射类 Method 来调用指定的方法。
123456789101112131415161718public class DebugInvocationHandler implements InvocationHandler { /** * 代理类中的真实对象 */ private final Object target; public DebugInvocationHandler(Object target) { this.target = target; } public Object ...
Java基础
基础概念与常识Java 语言有哪些特点?
简单易学
面向对象(封装,继承,多态)
平台无关性( Java 虚拟机实现平台无关性)
可靠性
安全性
支持网络编程并且很方便( Java 语言诞生本身就是为简化网络编程设计的,因此 Java 语言不仅支持网络编程而且很方便)
编译与解释并存
什么说 Java 语言“编译与解释并存”?高级编程语言按照程序的执行方式分为编译型和解释型两种。简单来说,编译型语言是指编译器针对特定的操作系统将源代码一次性翻译成可被该平台执行的机器码;解释型语言是指解释器对源程序逐行解释成特定平台的机器码并立即执行。
Java 语言既具有编译型语言的特征,也具有解释型语言的特征,因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(\*.class 文件),这种字节码必须由 Java 解释器来解释执行。因此,我们可以认为 Java 语言编译与解释并存。
Java 和 C++的区别?
都是面向对象的语言,都支持封装、继承和多态;
Java 不提供指针来直接访问内存,程序内存更加安全;
Java 的类是单继承的,C++ ...