Java的六种存储类型

来源:互联网 发布:淘宝安全中心首页网页 编辑:程序博客网 时间:2024/06/06 03:58

Thinking in java里,列举了Java的六种存储类型 
1.寄存器 
编写过汇编程序的应该对寄存器非常熟悉,那时候用的axbxcxdx等等。寄存器在CPU里面,所以速度非凡快,但是数量非常有限。在java中无法直接和寄存器打交道,不过在c中是可以声明寄存器变量的。 

2.栈空间 
写过汇编的肯定感到非常亲切,在汇编程序里不就是压栈和出栈吗?有一个指针控制栈空间,分配空间是栈指针上移,就是push操作,释放空间指针下移,就是pop操作。当然CC++也主要是通过栈分配空间的。因为只要压栈和出栈,所以速度非凡快。java中的对象引用是通过栈分配的,而java对象不是通过栈分配的,这也是java效率相对差一些的原因吧。通过栈分配空间有一个限制就是必须在编译时确定空间大小,也就是程序运行前就应该可以知道运行时内存的情况。比如mov ax4这条指令占用多少个字节在编译时是确定的。 

3.堆空间 
就是一个大的内存块,需要的时候就申请分配,java中的对象都是在堆中非配的。但是堆空间的回收是比较麻烦的,所以JVM的回收算法都比较复杂。但是假如堆空间比较大,也就是内存没有面临用完的话,JVM一般不会启动垃圾回收器。这种情况下堆的效率和栈应该差不多,只是堆没有回收空间而已。假如要不时的启动GC的话,可以想象效率会极其低下。 

4.静态存储区 
声明为static的变量因为他们一直存在(整个程序运行过程中),所以他们被保存在一个静态存储区。 

5.常量储存区 
声明为final static的为常量,可以保存在常量储存区,还有String类型的对象都是常量,系统维护了一个String常量池。 

6.其他存储 
RAM存储器,主要就是磁带,磁盘等等。 

这里最要害的应该是栈和堆,栈应该是应用最广泛的,在汇编中函数调用的时候一般是这样的过程: 
1.压栈(保护现场) 
2.进入方法调用 
3.出栈(恢复现场) 
这里只是简单的描述,上面的过程可能会有好多嵌套,不过大致过程就是这样,在其他语言其实也是一样的。

 

有六个地方都可以存储数据: (1) 寄存器(Registers)。这是速度最快的存储场所,因为寄存器其他所有存储媒介都不同:它位于处理器内部。不过,寄存器的数量十分有限,所以寄存器是根据需要由编译器适当地分配。作为一个程序员,我们对此没有直接的控制权,也没办法在程序里头感觉到寄存器的任何存在迹象。 (2) Stack()。位于一般的RAMrandom-access memory,随机访问内存)中。处理器通过其指针(“栈指针stack pointer)获得处理的直接支持。栈指针若向下()移,会分配新的内存;若向上()移,则会释放那些内存。这是一种特别快、特别有效率的数据存储方式,速度仅次于寄存器。由于Java编译器有责任产生stack指针前后移动的程序代码,所以它必须能够完全掌握它所编译的程序中存在stack里头的所有数据的实际大小和存活时间。如此一来便会限制程序的弹性。由于这个限制,尽管有些Java数据要存储在栈里——特别是对象句柄,但Java对象并不放到其中。 (3) Heap()Heap是一种通用性质的内存存储空间(也存在于RAM中),用来置放所有Java对象。内存堆Heap)胜过stack之处在于,编译器不需知道究竟得从堆里分配多少存储空间,也不需知道从堆上分配的空间究竟要存活多长的时间。因此,用堆存储数据时会得到更大的灵活性。要求创建一个对象时,只需用new即可。执行这些代码时,会在堆里分配空间。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会比从栈里分配花掉更长的时间(假设你真的可以在Java中像C++一样地从stack上产生对象的话)! (4) 静态存储空间(Static storage)。这儿的静态Static)是指位于固定位置(也在RAM里头)。静态存储空间存放着程序运行期间一直存在的数据。可用static关键字将某个对象内的特定成员设为静态,但Java对象本身永远都不会置入静态存储空间。 (5) 常量存储空间(Constant storage)。常量值通常被直接置于程序代码里头。因为它们永远都不会改变,所以也是安全的。有的常数需要严格地保护,所以可考虑将它们置入只读存储器(read-only memory,ROM)中。 (6) RAM存储空间(Non-RAM storage)。若数据完全存活于程序之外,则程序不运行时数据仍继续存在,脱离了程序的控制范围。其中两个最主要的例子便是串流化对象(streamed objects持久性对象(persistent objects。在串流化对象形式中,对象会被转换为一连串的字节(bytes)流,这些bytes通常会被传送给另一台机器。而在持久性对象形式中,对象被存储于磁盘,即使程序运行结束,这些对象还能够继续保有。这种类型的存储空间的特点在于,它们能够将对象转换为可存储于其他媒介的形式,并在需要时,将所存储的数据还原成可存储于RAM中的一般对象。Java提供了对轻量级持久性(Lightweight persistence的支持。新版本有可能提供更完善的解决方案。 针对你的补充我也补充一下:堆内存和栈内存确实是我们常常用的东西,比如 Animal a = new Animal(); 这个时候相当于在堆内存中开辟了一个空间保存了Animal的信息以及着块空间的内存地址,然后在栈内存中划了一小快空间保存了堆中的内存地址,这个时候我们就可以说引用a指向Animal()可是有时候,有个静态类.Animal,里面有个静态方法speak(); 那么可以这么直接调用Animal.sepak(); 这个时候既没有new,也没有Animal a=??; 所以既没有在堆中开辟空间也没有在栈内存中开辟空间 可是方法确实能执行,一切程序都运行在内存里,那么证明有新的内存区,就是静态空间了当然还有常量什么的等等

 

1. Java有几种内存?每一种内存有什么功能?哪一种内存速度快?

 

答案2

堆是先进先出,而栈是先进后处 

 

1. (stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。 

 

2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢 

还有人有更好的补充吗,无论什么样的答案,只要您愿意写,都表示感谢!

0 0