JVM的内存结构,如下如所示:
根据上图,JVM的内存结构包括:
方法区、堆区、直接内存、栈(本地方法栈,虚拟机栈)、程序计数器。
1、方法区:
1-1、存放的内容(类的信息,类static属性,方法,常量池):如已经加载的类的名称,修饰符,类中的static变量,类中的field信息,类中定义为final的常量,类的方法信息,运行时常量池。
注意的是,jdk1.7中,常量池在堆中,jdk1.8常量池在方法区里面。
1-2、内存回收的主要目标:对类的卸载,针对常量池的回收。
1-3、方法区是线程共享的。
2、堆:
2-1、存放的内容:对象的实例,即new出来的对象,类中的实例变量会随着对象实例的创建一起分配到堆中,还有就是存放数组值。方法中的变量和引用会在方法执行的时候压入栈中。
2-2、内存划分:分为新生代区和老年代区,新生代区:一个Eden区,两个S区,默认比例8:1:1,堆是垃圾回收机制主要工作的对象。
2-3、堆是线程共享的。
3、直接内存:
3-1、JVM虚拟机之外的机器内存。
4、本地方法栈和jvm虚拟机栈:
4-1、这两个栈没什么本质区别,唯一的区别就是本地方法栈是执行native方法的。
4-2、JVM是基于堆栈的虚拟机,JVM为每一个新创建的线程都分配一个堆栈,所以堆栈线程私有的区域,对一个java程序来说,他的运行是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态,JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。 我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的. 从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。