栈、堆、方法区简介

来源:互联网 发布:js offsetparent属性 编辑:程序博客网 时间:2024/04/28 23:19

一. 栈、堆、方法区的简介

    栈(stack): 1.为每个方法分配一个栈帧,栈帧之间不共享 
                       2.存放局部变量:基本数据类型和对象的引用 
    堆(head): 1.存放对象 
                       2.被所有线程共享 
    方法区(methodArea): 1.被所有线程共享 
                                         2.存放整个程序中永远唯一的元素:class(字节码指令),static(静态变量)和字符串常量

二. 举例子,详细阐述

    以举例子的方式,介绍一个段代码在栈、堆、方法区中的内存分配情况和执行流程。

2.1 需要所举例子的元素

    下面需要两个元素,第一:栈、堆、方法区的模型;第二:执行的一小段代码。

2.1.1 需要的栈、堆、方法区的模型

2.1.2 需要的代码

package test01;public class StackHeadMethod {public static void main(String[] args) {int a = 1;String b = "testBName";Test test = new Test();test.testMethod(a, b);}}class Test {private int testA;private String testB;private static final int testC = 2;public void testMethod(int testA, String testB){this.testA = testA;this.testB = testB;}}

三、进行内存分配流程的阐述

    首先,JVM将StackHeadMethod.class、Test.class装载到方法区(JVM会执行启动类装载器、扩展类装载器和类路径装载器,在此只详细讲解针对本测试代码的字节码文件的执行)。其中方法区中的2是Test.java中的静态变量,在类加载的时候就在方法区中的静态存储空间分配内存。

    然后,在StackHeadMethod.class文件中,找到main方法,开始执行main方法。将main方法在栈中开辟一个空间,称为栈帧。执行下面07、08、09、17、18、19行代码。
package test01;public class StackHeadMethod {public static void main(String[] args) {int a = 1;                // 在栈中分配内存空间String b = "testBName";   // 在栈和方法区中分配内存空间Test test = new Test();   // 在栈中堆中分配内存空间test.testMethod(a, b);}}class Test {private int testA;    // 在堆中分配内存空间private String testB; // 在堆中分配内存空间private static final int testC = 2; // 在堆和方法区中分配内存空间public void testMethod(int testA, String testB){this.testA = testA;this.testB = testB;}}

    再然后,执行test.testMethod(a, b);这一行,在栈中新分配一个栈帧,调用test中的testMethod方法。
package test01;public class StackHeadMethod {public static void main(String[] args) {int a = 1;                String b = "testBName";   Test test = new Test();   test.testMethod(a, b);  // 在栈中分配空间}}class Test {private int testA;private String testB;private static final int testC = 2;public void testMethod(int testA, String testB){  this.testA = testA;this.testB = testB;}}

    最后,testMethod方法执行完之后,testMethod栈帧从栈中释放空间,然后main方法执行完之后,main栈帧也释放空间,最后堆中的对象和方法区中的静态变量、字符串和字节码指令都没被使用时,根据java虚拟机的垃圾回收机制,进行对垃圾的回收。
    以上,是执行一段代码,对内存进行开辟和释放的整个过程。