一、JAVA 的六种存储地址
- 寄存器 register
位于处理器外部,是最快的储存器,然而数量极其无限。由编译器依据需要进行调配,不能由代码管制,对于开发者来说是 无感知 的。 - 堆栈 stack
位于 RAM 中,堆栈指针下移调配新的内存,上移开释内存。创立程序的时候,编译器必须晓得存储在堆栈中所有数据的确切大小和生命周期。某些 JAVA 数据存储在堆栈中——特地是对象援用,然而 JAVA 对象不存储其中。 - 堆 heap
位于 RAM 中,相比堆栈的劣势是不须要晓得从堆里调配多少存储空间以及存活工夫。JAVA 对象存储在这里。 - 动态存储 static
这里的“动态”是指“在固定的地位”。动态存储里存放程序运行时始终存在的数据。你可用关键字 static 来标识一个对象的特定元素是动态的 - 常量存储 constant
常量值通常间接寄存在程序代码外部,这样做是平安的,因为它们永远不会被扭转。有时,在嵌入式零碎中,常量自身会和其余局部宰割来到,所以在这种状况下,能够抉择将其放在 ROM 中。 - 非 RAM 存储
如果数据齐全存活于程序之外,那么它能够不受程序的任何管制,在程序没有运行时也能够存在。
二、栈、堆、办法区存储的内容
-
堆区:
- 存储的全副是对象,每个对象都蕴含一个与之对应的 class 的信息。(class 的目标是失去操作指令)
- jvm 只有一个堆区 (heap) 被所有线程共享,堆中不寄存根本类型和对象援用,只寄存对象自身。
-
栈区:
- 每个线程蕴含一个栈区,栈中只保留根底数据类型的值和对象以及根底数据的援用
- 每个栈中的数据 (根底数据类型和对象援用) 都是公有的,其余栈不能拜访。
- 栈分为 3 个局部:根本类型变量区、执行环境上下文、操作指令区(寄存操作指令)。
-
办法区:
- 又叫动态区,跟堆一样,被所有的线程共享。办法区蕴含所有的 class 和 static 变量。
- 办法区中蕴含的都是在整个程序中永远惟一的元素,如 class,static 变量。
三、JAVA 根本数据类型的存储
根本类型一共有 8 种,即 int, short, long, byte, float, double, boolean, char。这种类型的定义是通过 int a = 3 的模式来定义的,称为 主动变量。值得注意的是 主动变量存的是字面值,不是类的实例。
例如 int a = 3,这里的 a 是一个指向 int 类型的援用,指向 3 这个字面值,整个过程种没有类的存在。字面值的数据大小可知,生存期可知(定义在程序块中,程序块退出后,字段值就隐没了),存在栈中。
栈有一个很重要的特殊性,就是存在栈中的数据能够共享
假如咱们同时定义 int a = 3; int b = 3;
编译器先解决 int a = 3;首先它会在栈中创立一个变量为 a 的援用,而后查找有没有字面值为 3 的地址,没找到,就开拓一个寄存 3 这个字面值的地址,而后将 a 指向 3 的地址。接着解决 int b = 3;在创立完 b 的援用变量后,因为在栈中曾经有 3 这个字面值,便将 b 间接指向 3 的地址。这样,就呈现了 a 与 b 同时均指向 3 的状况。
特地留神的是,这种字面值的援用与类对象的援用不同。假设两个类对象的援用同时指向一个对象,如果一个对象援用变量批改了这个对象的外部状态,那么另一个对象援用变量也即刻反映出这个变动。相同,通过字面值的援用来批改其值,不会导致另一个指向此字面值的援用的值也跟着扭转的状况。
如上例,咱们定义完 a 与 b 的值后,再令 a =4;那么,b 不会等于 4,还是等于 3。在编译器外部,遇到 a =4;时,它就会从新搜寻栈中是否有 4 的字面值,如果没有,从新开拓地址寄存 4 的值;如果曾经有了,则间接将 a 指向这个地址。因而 a 值的扭转不会影响到 b 的值。