Java程序中新建的对象一般都是存放在堆中,而JVM是基于栈的架构,每个线程都会有一个虚拟机栈,而虚拟机栈中有着一个个的栈帧,每一个栈帧对应着一个方法,每个栈帧中都有着局部变量表,操作数栈,动态连接,返回出口等附加信息,局部变量表也是可以用来存放变量的,这变量可能只是引用,也可能就是具体实例,那么在方法体内声明的基本数据类型,是分配在堆还是栈上?

先修改虚拟机运行参数如下:

-Xmx10m :最大堆大小
-Xms10m :初始化堆大小
-XX:+PrintGC:打印GC日志

测试demo1:

public static void main(String[] args) {
    byte[] bytes = new byte[6 * 1024 * 1024];
    System.gc();
    System.out.println("--------------------------------------------------");
    byte[] byte2 = new byte[1024 * 1024];
    System.gc();
}

运行结果如下:在这里插入图片描述
可以发现第一次GC,堆内存被占用了6M左右,而在第二次GC后,堆内存被占用了7M左右,而代码中定义的byte数组的大小刚好是7M,所以可以知道,byte[]数组对象被分配在了堆上。

测试demo2:

public static void main(String[] args) {
    byte[] bytes = new byte[6 * 1024 * 1024];
    System.gc();
    System.out.println("--------------------------------------------------");
    int a = 0;
    long b = 0;
    double c = 1.0;
    char d = '1';
    short e = 1;
    boolean f = true;
    float g = 1;
    System.gc();
}

运行结果如下:在这里插入图片描述
从输出结果可以发现,即使在第一次GC后分配了一连串的基本数据类型,第二次GC后堆所占的内存大小还是比第一次GC要小的。

总结

通过以上测试结果,可以知道如果方法体内声明的基本数据类型,是分配在堆上的话,那么测试demo2的第二次GC后的堆所占内存大小应该要比第一次GC的大,类比测试demo1的效果,所以可以逆向证明,方法体内声明的基本数据类型,是分配在栈上的。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐