System.gc()和Runtime.gc()都可以提醒jvm进行垃圾回收,但是什么时候执行不一定
线程私有的
程序计数器
java虚拟机栈
描述的是java方法执行的内存模型:每个方法在执行的同时会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈道出栈的过程。
局部变量表:
存放了编译期可知的各种基本数据类型、对象引用(reference类型)和returnAddress类型(指向一条字节码指令的地址)。
局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
本地方法栈
与虚拟机栈所发挥的作用非常相似,只不过本地方法栈是为虚拟机使用到的Native方法服务(比如java调用c库)
线程公有的
方法区:
存放已被虚拟机加载的类的信息、常量、静态变量、即时编译器编译后的代码等数据
- 类的信息: 类的版本、字段、方法、接口等描述信息
- 运行时常量池: 用于存放编译期生成的各种字面变量和符号引用,这部分内容将在类加载进入方法去的运行时常量池中存放。
java堆。:
对大多数应用来说是java虚拟机所管理的内存中最大的一块。是垃圾收集器管理的主要区域。
此内存区域的唯一目的就是存放对象实例。
java虚拟机规范吧它描述成堆的一个逻辑部分,但它的别名叫做Non-Heap(非堆)。
被HotSpot的使用者叫做永久代(Permanent Generation)
Heap(堆) | Stack(栈) | |
---|---|---|
JVM中的功能 | 内存数据区 | 内存指令区 |
存储数据 | 对象实例 | 基本数据类型, 指令代码,常量,对象的引用地址 |
详细 | 保存对象实例,实际上是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在stack中)。对象实例在heap中分配好以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对象实例在heap中的位置,便于找到该对象实例。 |
堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。"
“栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。