P46页有感java
寄存器位于CPU内部,这是计算机硬件中处理速度最快的地方,是真正的处理程序的位置。寄存器是由编译器根据须要来分配的,而且即使是编译器,也须要经过操做系统的抢占式调度才可以得到CPU的处理权,所以,寄存器的存储空间时很是有限的,开发人员对寄存器没有直接的控制权,在程序里也无法对寄存器有什么操做。程序员
堆栈通常也叫栈,通常指的是RAM区域,处理速度仅次于寄存器。在堆栈中,通常存放的都是对象的引用,当栈指针下移的时候,就建立新的内存,反之则释放内存。当建立一个对象时。该对象的会被放到堆内存的空间,而该对象的引用则会被放到栈内存中。而且Java 编译器必须准确地知道堆栈内保存的全部数据的“长度”以及“存
在时间”。以便回收空间和知道栈内存还剩余多少空间。编程
堆内存也是在RAM区域,它是对象的真正存放位置,当new一个对象时,该对象就会被存放至堆内存,而且Java编译器不须要去在乎堆中还剩多少空间,Java 有一个特别 的“垃圾收集器”,它会查找用new建立的全部对象,并辨别其中哪些再也不被引用。随后,它会自动释放由 那些闲置对象占据的内存,以便能由新对象使用。这意味着咱们根本没必要操心内存的回收问题。只需简单地建立对象,一旦再也不须要它们,它们就会自动离去。这样作可防止在C++里很常见的一个编程问题:因为程序员忘记释放内存形成的“内存溢出”,对象的销毁---对象的引用放在栈中,因此使用完引用就被从栈中销毁了,可是实际的对象仍然存放在堆中,只有在没有任何的引用使用它的时候才被垃圾回收器销毁掉。安全
class StaticTest { Static int i = 47; } //如今咱们 new两个对象 StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest(); //st1.i和st2.i都是47 尽管咱们制做了两个StaticTest对象,但它们仍然只占据StaticTest.i的一个存储空间。这两个对象都共享一样的i 此时不论是哪一个对象执行st1++,另外一个对象的i也会加一
常数存储。常数值一般直接置于程序代码内部。这样作是安全的,由于它们永远都不会改变。有的常数 须要严格地保护,因此可考虑将它们置入ROM。学习
非RAM存储。若数据彻底独立于一个程序以外,则程序不运行时仍可存在,并在程序的控制范围以外。 其中两个最主要的例子即是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,一般会发给 另外一台机器。而对于固定对象,对象保存在磁盘中。即便程序停止运行,它们仍可保持本身的状态不变。对 于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其余媒体中。一旦须要,甚至能将它们恢复 成普通的、基于RAM的对象。Java 1.1提供了对Lightweight persistence的支持。将来的版本甚至可能提 供更完整的方案。操作系统
在Java编程思想中对于基本数据类型的存储位置有这么一句话线程
对于这些基本类型,Java 采纳了与C和C++相同的方法。也就是说,不是用 new建立变量,而是建立一个并不是引用的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,可以更 高效地存取。指针
可是我百度查找了一些相关资料,也有说基本数据类型有放在堆中的。梳理一下,首先,八大基本类型都不能看作对象,基本类型的存储位置要分状况,当基本类型的建立是在类中。像这样code
class Demo{ int a = 1;//状况1 public int test(){ int b = 2;//状况2 } }
在状况1下,建立的是全局变量。是随着对象一块儿存放在堆中的,在状况2下,建立的是局部变量,每当程序调用方法时,系统都会为该方法创建一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束,这就局部变量只能在方法中有效的缘由。因而可知,基本类型并非彻底存储在栈区的。缘由是由于,上面基础知识提到的,堆是全部线程共享的内存区域,栈 是每一个线程独享的。若是你将一个实例变量放在栈内,那么就不存在多个线程访问同一个对象资源了,这显然是不对的,因此全局变量要在堆上建立,也不是线程安全的。可是对于局部变量,是在栈上建立的,每一次方法调用建立一个方法栈,独享一分内存区域,其余的线程是不会访问到该线程的资源,在 栈上建立也会减轻GC的压力,随着该方法的结束,相对应的方法栈内存消除,这种局部变量占用的内存天然就消失了,所以局部变量是线程安全的。对象