java的内存划分
内存就是计算机当中的内存条,程序如果想运行,需要开辟一块内存空间,计算机当中的整体内存是由操作系统管理的,java需要申请内存才可以运行,申请的内存划分为五个部分,不同的部分管理不同的功能
1.栈(Stack):里面存放的是方法中的局部变量。(方法的运行一定要在栈中。)局部变量:方法的参数,或者是方法{}内部的变量。
作用域:一旦超出作用域(大括号),立刻从栈内存中消失。
2.堆(Heap):凡是new出来的东西,都在堆内存当中,比如,数组。堆内存当中都有一个地址值:16进制,堆里面的数据都有默认值
3.方法区(Method Area):存储.class相关信息,包含方法信息。
4.本地方法栈(Native Method Stack):与操作系统相关。
5.寄存器(pc Register):与cpu相关。
基本数据类型
基本数据类型有8种,它们存储于栈中。
int num = 5,这里的 num 是一个指向 int 类型的引用,指向5这个字面值。这些字面值的数据,由于大小可知,生存期可知,出于追求速度的原因,就存在于栈中。
栈中的数据共享:已存在的值不会再次创建
int a = 3;
int b = 3;
编译器先处理 int a = 3;首先它会在栈中创建一个变量为 a 的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将 a 指向3的地址。接着处理 int b = 3;在创建完 b 这个引用变量后,由于在栈中已经有3这个字面值,便将 b 直接指向3的地址。这样,就出现了 a 与 b 同时均指向3的情况。
对象
Person类:
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
一个类通过使用new运算符可以创建多个不同的对象实例,这些对象实例将在堆中被分配不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。
Person one = new Person("小明",15);
Person two = new Person("小王",17);
在堆内存中只创建了一个对象实例,在栈内存中创建了两个对象引用,两个对象引用同时指向一个对象实例。
Person one = new Person("小明",15);
Person two = one;
包装类
基本类型的定义都是直接在栈中,如果用包装类来创建对象,就和普通对象一样了。
比如int a = 5,a存储在栈中。而Integer i = new Integer(5),i 对象数据存储在堆中,i 的引用存储在栈中。
数组
数组是一种引用类型,数组用来存储同一种数据类型的数据,一旦初始化完成,即所占的空间就已固定下来,即使某个元素被清空,但其所在空间仍然保留,因此数组长度将不能被改变。
举例:执行int[] array = new int[5]时,首先会在栈中创建引用变量,在堆中开辟5个int型数据的空间,该引用变量存放数组首地址,即实现数组名来引用数组。
静态变量
static 的修饰的变量和方法会存在静态域,类变量会共同使用同一块变量地址。即改变该静态变量,该所有类对象所使用的变量值都会随之改变。