首先咱们来讲说内存,由于从内存的角度来出发来分析一些变量,引用或者对象的生命周期会更好理解一些。java
java是一门编程语言,他跟C++有什么不一样呢?本质上,他们都是同样的,异曲同工。由于底层都是操做内存和磁盘的工具,只是语法不一样,表现形式不一样而已。程序员
因此有的时候没必要刨根问底,由于这可能只是语言的一种规则而已。编程
java中都是以对象和对象的引用形式来操做数据的,那么java中是如何分配这些存储引用和内存的呢?编程语言
1. 寄存器。这是最快的存储区,觉得它位于不一样于其余存储区的地方——处理器内部。可是寄存器的数量极其有限,因此寄存器根据需求进行分配。你不能直接控制,也不能在程序中感受到寄存器存在的任何迹象。工具
2. 栈(又名堆栈),原型就是碟盘子模型,先放的盘子后拿。栈位于通用RAM(随机访问存储器)中,但经过堆栈指针能够直接从处理器那里得到直接支持。经过栈顶指针的上下移动来建立和释放内存,这是一种快速有效的分配存储的方法,仅次于寄存器。可是这种方式,java系统必须知道存储在堆栈内全部项的生命周期,以便上下移动堆栈指针。因此对象的引用存在与堆栈中(由于由确切的生命周期),可是对象不会存于堆栈中(无确切的生命周期)。spa
3.堆。一种通用的内存池,也是位于RAM区,用于存放全部的java对象。堆不一样与堆栈的好处是:编译器不须要知道存储的数据在堆里存活多长时间。所以,在堆里分配存储由很大的灵活性。当须要一个对象时,只需new一个,当执行时,会自动在堆里进行分配内存。固然,为了这种灵活性必须付出相应的代价:用堆进行存储分配和清理可能比用堆栈进行存储分配须要更多的时间。(对比于C++,对象会在栈中存储,由于对象的生命周期都是程序员本身控制的)指针
4.常量存储。常量值一般直接存放在程序代码的内部。对象
5.非RAM存储。若是数据彻底存活于程序以外,那么能够不受程序的任何控制,在程序没有运行时也能够存在。其中两个基本的例子就是流对象和持久化对象。在流对象中,对象转化成字节流,一般被发送给另外一台机器。在持久化对象中,对象被存放于磁盘上,所以,即便程序终止,他们仍能够保持本身的状态。这种存储方式的技巧在于:把对象转化成为能够存储在其余媒介上的事物,在须要时,可恢复成常规的、基于RAM的对象。java提供了对轻量级持久化的支持。生命周期
java对于小的,基本的变量是这样处理的:内存
将他们固定长度,直接存储值于堆栈中,因此java的基本类型都是有固定取值范围的。
java基本类型长度不变也是java的可移植性的重要缘由。
变量的生命周期每每是由大括号决定的,而对象则否则
{
String s = new String("a string");
}
在上面的这段代码中,引用s在做用域终点就消失了。然而,s指向的String对象仍然继续占据着内存空间。
咱们已经没法在做用与以外访问这个对象,由于他惟一的引用已经失效了。
事实证实,由new建立的对象,只要你须要,就会一直保留下去。
那么他们何时消亡,以致于不会填满内存呢?这就引出了垃圾回收器。
垃圾回收器的做用:监视new建立的全部对象,并辨识哪些对象是不会再被引用的对象,随后,释放这些对象的内存空间,以便供其余新的对象使用。因此对象不须要程序员本身回收。神奇的GC...
3、有关static
class StaticTest {
static int i = 47;
}
即便你建立了两个StaticTest对象,StaticTest.i也只有一份存储空间,这两个对象共享一个i。
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
在这里,st1.i和 st2.i指向同一存储空间,所以他们具备相同的值47.
因此static字段对每一个类来讲只有一份存储空间,而非static字段则是对每一个对象有一个存储空间。