1、进程
程序和进程的区别:(1)程序是静态的,就是存放在磁盘里的可执行文件,就是一系列的指令集合;(2)进程是动态的,是程序的一次执行过程,同一程序多次执行会对应多个进程。
(1)进程是系统进行资源分配的一个独立单位
(2)进程的组成:从结构上看,进程由 PCB、程序段、数据段 组成
-
① PCB【Process Control Block,进程控制块】
包括:进程描述信息、进程控制和管理信息、资源分配清单、处理机相关信息等
不同状态的进程(就绪、阻塞)的PCB被用链接或索引方式组织起来,以方便系统对进程的调度和管理:
-
② 程序段
程序的代码(指令序列)。注意:多个进程可运行同一个程序
-
③ 数据段
运行过程中产生的各种数据
运行程序:
(3)进程的特征
- 动态性:进程是程序的一次执行过程,是动态地产生、变化、消亡的;
- 并发性:内存中有多个进程实体(可理解为进程在执行过程中某一时刻的一个快照或状态),各进程可并发执行;
- 独立性:进程可独立运行、独立获得资源;
- 异步性:各进程按各自独立的,不可预知的速度推进;
- 结构性:每个进程都会配置一个PCB,从结构上看,进程由PCB、程序段、数据段组成;
2、线程
(1)线程是一个基本的CPU执行单元,也是程序执行流的基本单位。线程使得一个进程内可并发处理各种任务。
(2)组成:由线程ID、程序计数器、寄存器集合 和 堆栈 组成
(3)线程可分为 用户级线程 和 内核级线程
在Hotspot(Oracle对于JVM的实现)中,线程模型是“一对一模型”,即上图中的内核级方式。
3、JVM中的进程与线程
程序员运行Java程序启动一个JVM进程:
运行一个Java程序 及 JVM运行时数据区内存结构:
其中,方法区:
“加载“ 阶段(虚拟机类加载的第一个阶段)结束后,Java虚拟机外部的二进制字节流就按照虚拟机所设定的格式存储在方法区中了,方法区中的数据存储格式完全由虚拟机实现自行定义的,《Java虚拟机规范》未规定此区域的具体数据结构。类型数据妥善安置在方法区之后,会在Java堆内存中实例化一个java.lang.Class类的对象(类加载与Class对象),这个对象将作为程序访问方法区的类型数据的外部接口。
方法区中存储已经被虚拟机加载的以下信息:
-
① 类型信息
全限定类名、访问修饰符、字段信息、方法信息、字节码指令(即代码)
-
② 常量
存放编译期生成的各种字面量与符号引用。
常量存放在运行时常量池中【运行时常量池:原本记录在Class文件中的常量池,此时被加载到方法区中,称为运行时常量池。常量池中每一项常量都是一个表,截至JDK13,常量池表中有17中不同类型的常量(如整型字面量、类或接口的符号引用、字段的符号引用等)】。
1)字面量:更接近于 Java 语言层面的常量概念,如文本字符串、被声明为 final 的常量值等;
2)符号引用:属于编译原理方面的概念,主要包括下面几类常量:
- 被模块导出或者开放的包(Package)
- 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
- 方法句柄和方法类型
- 动态调用点和动态常量
-
③ 静态变量
类变量,即被 static 修饰的变量。
在 JDK 7 及 之前,HotSpot 使用永久代来实现方法区时,类变量所使用的内存在 ”准备“ 阶段(虚拟机类加载的一个阶段)分配并设置类变量初始值(零值);而在 JDK 8 及 之后,类变量则会随着 Class 对象一起存放在 Java 堆中,这时候 ”类变量“ 在方法区就完全是一种逻辑概念的表述。
-
④ 即时编译器编译后的代码缓存
注意:方法区的变更: