JVM和运行的JAVA代码一样都是一个进程
进程运行就需要从系统中申请资源,内存就是其中比较重要的资源
内存空间支撑着JAVA进程的执行
JAVA中定义一个变量就需要内存
- 内存是由JVM先向系统申请
- 再给到Java中的
一、区域的划分
JVM申请到的空间,给java使用的时候,会根据不同的用途分配不同的空间
1.Heap堆区
代码中New 出来的对象,就存放在堆中
对象持有的非静态成员,也存放在堆中
2.栈 本地方法栈/虚拟机栈
虚拟机栈:!!!记录的是JAVA中的
包含了 方法调用关系 和 局部变量
方法调用关系:比如A调用了B中的方法,那么代码会在B中方法执行完之后,需要回到A
而方法调用关系就是记录了这个调用关系,让代码回到A继续执行
本地方法栈:!!!记录的是JVM内部的
JVM内部通过C++写的代码,调用的关系和局部变量
作为一个Java仔,一般的栈指的是虚拟机栈,本地方法栈不怎么需要关注
!!!!!!这里的的堆和栈, 和数据结构中的堆栈不是同一个东西
JVM中的堆栈是JVM划分的内存区域
3.程序计数器
属于一个比较小的空间
专门存储下一条要执行的Java指令的地址
4.元数据(就是元数据)
这是一个计算机中常见术语
指的是具有辅助性质,描述性质的属性
比如在硬盘上存储文件数据,不仅仅包括数据本身还包含了他的元数据
元数据:比如文件大小、文件位置、文件拥有者、文件的修改时间、文件的权限信息等等
类的信息/方法的信息
一个程序中有哪些类,类又有哪些方法,每个方法包含了哪些指令
都记录在了元数据区
我们写的JAVA代码,if,while等等,以及各种逻辑运算
- 最终都会被转换成JAVA字节码(由JAVAC完成)
- 此时这些字节码在运行时就会被JVM加载到内存中放到元数据区(方法区)中
- 当前程序要如何执行,就会按照元数据区里记录的字节码,依次执行
JVM中堆和元数据区只有一份
而栈和程序计数器可能有N份
栈和程序计数器的个数和线程有关,比如
线程1和线程2各有一个栈来记录各自的调用过程
各有一个计数器来决定各自线程下一步应该执行哪个指令
t,n,m 分别存放在JVM的哪个区?
t : 栈区
是main方法中的一个局部变量
n:堆区
是T类中的非静态成员属性
m:元数据区
带有static修饰的变量,是在类对象中的
而,类对象就相当于是T.class
JVM把.class文件加载到内存之后,会把里面的信息用一个对象来表示,也就是类对象(T.class)
类对象包含了一系列信息
比如:类的名称,类继承自哪个类,实现了哪些接口
都有哪些属性,属性的名称,类型,权限
都有哪些方法,方法的名称,参数,权限
区分一个变量在哪个内存的区域,主要看变量的“形态” (局部变量,成员变量,静态成员变量...)