Jvm 主要组成部分及作用
JVM包含两个子系统和两个组件,
两个子系统
- Class loader(类装载) :根据给定的全限定名类名(如: java.lang.Object)来装载class文件到
Runtime data area中的method area - Execution engine(执行引擎) :执行classes中的指令
两个组件
- Runtime data area(运行时数据区) :JVM的内存
- Native Interface(本地接口):与native libraries交互,是其它编程语 言交互的接口。
java程序运行机制步骤
-
首先利用IDE集成开发工具编写Java源代码,源文件的后缀为.java;
-
再利用编译器(javac命令)将源代码编译成字节码文件,字节码文件的后缀名 为.class;
-
运行字节码的工作是由解释器(java命令)来完成的。
-
java文件通过编译器变成了.class文件,接下来类加载器又将这 些.class文件加载到JVM
中然后交给解释器执行引擎将字节码编译成底层系统指令交给CPU执行。
其实可以一句话来解释:类的加载指的是将类的.class文件中的二进制数据读入 到内存中,将其放在运
行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结
构。
JVM 运行时数据区(虚拟机内存)
-程序计数器:当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的 字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个 计数器来完成;
-
Java 虚拟机栈:用于存储
局部变量表
、操作数栈
、动态链接
、方法出口
等信息; -
本地方法栈:与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java方法的,而本地方法栈是为虚拟机调用
Native
方法服务的; -
Java 堆:Java 虚拟机中内存大的一块,是
被所有线程共享,几乎所有的对象实例都在这里分配内存
; -
方法区(Methed Area):用于存储已被虚拟机加载的
类信息、常量、静态变量
、即时编译后的代码等数据。
关于虚拟机深拷贝和浅拷贝在虚拟机的表现
- 浅拷贝: 只是增加了一个指针指向已存在的内存地址,
- 深复制:在计算机中开辟一块新的内存地址用于存放复制的对象。
堆栈
常说的堆栈有什么区别
物理地址
堆的物理地址分配对对象是不连续的。因此性能慢些。在GC的时候也要考虑到不连续的分配,所以有
各种算法。比如,标记-消除,复制,标记-压缩,分代 (即新生代使用复制算法,老年代使用标记压缩) 栈使用的是数据结构中的栈,先进后出的原则,物理地址分配是连续的。所以性能快。
内存分别
堆因为是不连续的,所以分配的内存是在运行期确认的,因此大小不固定。一般 堆大小远远大于栈。
栈是连续的,所以分配的内存大小要在编译期就确认,大小是固定的。
存放的内容
堆存放的是对象的实例和数组。因此该区更关注的是数据的存储
栈存放:局部变量,操作数栈,返回结果。该区更关注的是程序方法的执行。