java 堆栈内存详解_Java学习之内存分析详解_栈_堆_方法区_栈帧_程序执行的内存变化过程...

Java虚拟机的内存可以分为三个区域:栈stack、堆heap、方法区method area。

栈(stack)的特点如下:

1、栈描述的是方法执行的内存模型,每个方法被调用都会在栈中创建一个栈帧(存储局部变量、操作数、出口等)。

2、Java虚拟机(JVM)为每个线程创建一个栈,用于存放该线程执行方法的信息(局部变量,实际参数等)。

3、栈属于线程私有,不能实现线程间的共享!

4、栈的存储特性是“先进后出”,(可以比喻为手枪弹夹的子弹)

5、栈是由系统自动分配的,速度块!栈是一个连续的内存空间!

堆(heap)的特点如下:

1. 堆用于存储创建好的对象和数组(数组也是对象)

2. JVM只有一个堆,被所有线程共享

3. 堆是一个不连续的内存空间,分配灵活,速度慢!

方法区(method area)(又叫静态区)特点如下:

1. JVM只有一个方法区,被所有线程共享!

2. 方法区实际也是堆,只是用于存储类、常量相关的信息!

3. 用来存放程序中永远是不变或唯一的内容。(类信息【Class对象】、静态变量、字符串常量等)

使用文字和图画描述,如下程序的执行过程:

public class TestObject {

public static void main(String[] args) {

Car c1 = new Car();

c1.changeColor("红色");

c1.showColor();

System.out.println(Car.tyreNum);

System.out.println(c1.tyreNum);

Car c2 = new Car();

Engine e = new Engine();

e.speed = 1000;

e.weight = 10;

c2.engine = e;

c2.color = "黑色";

c2.tyreNum = 10;

System.out.println(c1.tyreNum);

}

}

class Car {

static int tyreNum = 4;

Engine engine;

String color; // char sequence :字符序列

void changeColor(String c) {

color = c;

}

void showColor() {

System.out.println("我的颜色是:" + color);

}

}

class Engine {

int speed;

int weight;

}

上述代码的内存分析如下:

文字解释:

1、javacTestObject.java //先将源代码编译成.class的字节码文件

2、java TestObject //启动JVM,TestObject类、Car类、Engine类先加载到空间(方法区)里边去

3、(1)main方法是程序的入口,同时也是静态方法,在方法区的TestObject类相关信息中找到main方法,JVM在栈中创建一个main方法的栈帧,同时开辟了一个Car类型的变量c1,当执行 new Car()的时候,在堆里面开辟空间,创建了一个Car类型的对象,使用默认的初始值,然后把该对象的地址值引用给变量c1。

(2)当执行c1.changeColor("红色")方法的时候,会在栈中创建一个changeColor方法的栈帧,该方法的作用是给变量c1指向的对象的color属性赋值,然后在方法区找到“红色”之后赋值,方法结束,栈帧销毁。

(3)执行c1.showColor()方法,首先在栈中创建栈帧,然后该方法的作用是调用System.out.println("我的颜色是:"+color),然后再去栈中创建一个println方法的栈帧,该方法是打印字符串出来,字符串在方法区的字符串常量中找到,然后color因为之前赋值是红色,所以控制台打印出:我的颜色是:红色

(4)

System.out.println(Car.tyreNum);

System.out.println(c1.tyreNum);

上面的两行代码也是两个方法,去创建栈帧,然后输出方法区里面的静态变量的值,一个是类名调用,一个是对象名调用,都能找到,因为静态变量从属于类,对象是可以访问加载到方法区类中的信息的,方法结束栈帧销毁。

(5)、在main方法的栈帧中,开辟空间存储Car类型变量c2,new Car()和上面一样都是去堆中开辟空间创建对象,把地址传给变量c2,这时候,c2指向的对象的成员变量还是使用默认值,都是null,null。

(6)、然后,在main方法的栈帧中,开辟空间存储Engine类型变量e,new Engine()在堆中开辟空间创建创建对象并且把地址值给变量e,然后执行代码给e指向的对象赋值,然后再把e的地址值赋值给对象c2的地址值,所以c2的成员变量engine指向对象e

(7)、通过对象c2去方法区中找到静态变量typeNum,并且赋值为10,可以修改静态变量,不过不建议使用,还是使用类名调用吧,最后在打印出来

(8)、main方法结束,销毁对应的栈帧。

执行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值