详解 堆,栈,方法区

示例:

class Birthday 
{
    private int day;  
    private int month;  
    private int year;      
    
	public Birthday(int d, int m, int y) 
	{
        day = d;   
        month = m;   
        year = y;  
    }  
}  
 
public class Test
{  
    public static void main(String args[])
	{ 	
        int date = 22;  
        Test test = new Test();        
        test.change(date);   
        Birthday bd= new Birthday(30,08,2001);         
    }    
 
public void change(int i)
{
	int i = 123;
}
对于上面这段代码:
1. 栈中:
  1. 局部变量及其数据:date = 22, i = 123, d = 30, m = 08, y = 2001
  2. 对象的引用:test, bd
2. 堆中
  1. 成员变量及其数据:day = 30, month = 08, year = 2001
  2. 对象:new Test(), new Birthday()
3. 方法区中:
  1. 方法: main(), change()
附图内存分配实例
执行顺序:
  1. main方法开始执行:int date = 22;
    date局部变量,基础类型,引用和值都存在栈中。
  2. Test test = new Test();
    test为对象引用,存在栈中,对象(new Test())存在堆中。
  3. test.change(date);
    i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
  4. Birthday bd= new Birthday(30, 08, 2001);
    bd为对象引用,存在栈中,对象(new Birthday())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new Birthday()里面)。当Birthday构造方法执行完之后,d,m,y将从栈中消失。
    5.main方法执行完之后,date变量,test,bd引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。

总结:

1. 栈:

  1. 局部变量(方法中):8种基本变量及其值—boolean、byte、char、short、int、float、long、double (不包含String—引用类型变量, 它只将变量放入栈中,而将值放入常量池)
  2. 对象的引用: 如 A a = new A(); 中的 a, String s = “哈哈” 中的 s. [而new A() 则存放与堆中, 哈哈 则存放于常量池中]
注:

每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程,栈中的数据随线程生灭,且线程间数据不共享.

2. 堆:

  1. 对象: 如上方的 new A()
  2. 数组: int [] date = {2019, 8, 22}; 中 {} 内的内容
  3. 成员变量及值: 在方法外的变量(包括引用类型—String)
附图(数组)

数组分配

3. 方法区:

  1. 方法:方法的名称和修饰符
  2. 常量: 被final修饰的成员变量, 常数, 字符串常量
  3. 静态变量(类变量):被static修饰
注(变量间关系):

变量间关系

附图:

内存分配图解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值