JAVA内存分析

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

栈的特点如下

  1. 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
  3. 栈属于私有线程,不能实现线程间的共享
  4. 栈的存储特性是“先进后出,后进先出”
  5. 栈是由系统自动分配,速度快,栈是一个连续的内存空间

堆的特点如下

  1. 堆用于储存创建好的对象和数组(数组也是对象)
  2. JVM只有一个堆,被所有线程共享
  3. 堆是一个不连续的内存空间,分配灵活,速度慢

静态区的特点如下

  1. JVM只有一个静态区,被所有线程共享
  2. 静态区实际也是堆,只是用于存储类、常量相关的信息
  3. 用来存放程序中永远不变或唯一的内容(类信息【Class对象】、静态变量、字符串常量等)

面向对象内存分析

下面通过代码来对面向对象的内存模型进行分析。创建Computer类,里面有一个brand(品牌)属性

public class Computer {
	
	String brand;
}

然后创建Student类

public class Student {
	
	int id;
	
	int age;
	
	String name;
	
	Computer computer;	// 电脑
	
	static String address = "上海";
	
	void study() {
		System.out.println("我再认真学习,使用电脑:" + computer.brand);
	}
	static void sayAddress() {
		System.out.println(address);
	}
	public static void main(String[] args) {
		
		Student student = new Student();
		student.id = 1001;
		student.name = "gavin";
		student.age = 18;
		
		Computer computer = new Computer();
		computer.brand = "联想";
		
		student.computer = computer;
		
		student.study();
		
	}
}

当程序运行后,内存示意图如下
图1.面向对象内存分配图
上图中

  1. 静态区的内存空间会最先分配,它的分配是在程序开始编译时完成的
  2. 对象都是在堆中开辟并分配内存,栈只是持有对象内存地址的引用
  3. 每个方法被调用都会创建一个栈帧,main方法以及main方法中的new Student()、new Computer()都会创建一个独立的栈帧

基本类型变量分配在堆还是栈?

通过上面的分析我们已经知道对象(也即引用类型变量)的内存都是分配在堆中的,栈只是持有堆内存地址的引用,那基本类型变量的内存是分配在堆还是栈呢?其实堆、栈都可以为基本类型变量分配内存,基本类型变量的分配要看声明的位置

  1. 如果基本类型变量定义在类中(也即成员变量),那么内存会直接分配在堆中,栈使用的话只是持有该内存地址的引用
  2. 如果基本类型变量定义在方法中或代码块中(也即局部变量),那么内存会直接分配在栈中。

可以总结如下

局部变量成员变量
基本数据类型变量名和值都在方法栈变量名和值都在堆内存
引用数据类型变量名在方法栈,变量名指向堆内存地址变量名和变量名指向的内存地址都在堆

如下面变量a的内存就是直接分配在栈方法中,而c1变量名分配在栈中,它实际指向堆中的computer对象内存地址

void study() {
	int a = 1;
	Computer c1 = this.computer;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值