`
yuhen78
  • 浏览: 14343 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

堆(heap)与栈 (stack)

阅读更多

堆与栈

堆(heap)与栈 (stack) 都是java用来在Ram(random access memory 随机存储器)中存放数据的地方。

java中自动管理heap 和 stack,程序员不能直接设置。

stack : 都是虚拟机stack。

 

堆是一个运行时数据区,对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式地释放。堆是由垃圾回收来负责的.

 

堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收 集器会自动收走这些不再使用的数据。

堆缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String、数组、对象等等)但不存放对象内容。
栈的优势是,存取速度比堆要快,仅次于寄存器,(不是寄存器)。栈数据可以共享。

缺点是,存在栈中的数据大小与生存期必须是 确定的,缺乏灵活性。

栈中主要存放一些基本类型的变量数据(int,short,long,byte,float,double,boolean,char)和对象引用。

引用在白皮书中直接指出是实际就是一个C的"指针"。
假设我们同时定义:

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=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,它是由编译器完成的,它有利于节省空间。

 

字符串
1. String不是基本数据类型,String是一个对象。因为对象的默认值是null,所以String的默认值也是null。它是一种特殊的对象,有其它对象没有的一些特性。

2. new String()和new String("")都是申明一个新的空字符串,是空串不是null。

3. String str="helloword"和String str=new String("helloword")的区别

示例:

String s0="helloword"; 
String s1="helloword"; 
String s2="hello" + "word"; 
System.out.println(s0==s1); 
System.out.println(s0==s2); 

 

结果为:
true
true

因为例子中的s0和s1中的"word"都是字符串常量,它们在编译期就被确定了,所以s0==s1为true。而"hello"和"word"也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中"helloword"的一个引用。

所以得出s0==s1==s2。用new String()创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

示例:

String s0="helloword"; 
String s1=new String("helloword"); 
String s2="hello" + new String("word"); 
System.out.println(s0==s1); 
System.out.println(s0==s2); 
System.out.println(s1==s2); 

 

结果为:
false
false
false
s0还是常量池中"helloword"的应用。s1因为无法在编译期确定,所以是运行时创建的新对象"helloword"的引用。s2因为有后半部分new String("word")所以也无法在编译期确定,所以也是一个新创建对象"helloword"的应用。

4. 关于equals()和==
这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true。而==是比较两字符串的地址是否相同,是否是同一个字符串的引用。

5. 关于String是不可变的
String的实例一旦生成就不会再改变了。比如说:String str="hello"+"word"+" "+"ans"; 就是有4个字符串常量,首先"hello"和"word"生成了"helloword"存在内存中,又和"ans"生成了"helloword ans";并把这个字符串的地址赋给了str,就是因为String的"不可变"产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。
下面是一些String相关的常见问题:
String中的final用法和理解

final StringBuffer a = new StringBuffer("111");
final StringBuffer b = new StringBuffer("222");
a=b;//此句编译不通过
final StringBuffer a = new StringBuffer("111");
a.append("222");//编译通过

 

可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。

总结
栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String、数组、对象等等)但不存放对象内容。

堆中存放使用new关键字创建的对象。

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定义(常量池和堆)。有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建。

分享到:
评论

相关推荐

    堆(heap)与栈(stack)的区别

    非常经典的资料,准确描述了C语言中,堆和栈之间的区别!是深入理解C语言的好材料

    java中堆(heap)和堆栈(stack)有什么区别

    "Java 中堆(heap)和堆栈(stack)的区别" Java 中堆(heap)和堆栈(stack)是两个不同的内存区域,分别用于存储不同的数据类型和对象。堆栈(stack)是 Java 中的一种内存区域,用于存储基本类型的变量和对象的...

    c语言stack(栈)和heap(堆)的使用详解

    1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据...

    堆(heap)和栈(stack)的区别

    一、预备知识—程序的内存分配 二、例子程序 3.windows进程中的内存结构

    stack&heap

    1,堆和栈存储; 2,堆和栈用法; 3,堆和栈管理; 4,堆和栈区别;

    The Run-time Heap and Stack

    一个介绍操作系统的堆和栈的入门文档,有图示:)

    堆内存和栈内存详解 ESP

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与...

    关于Java栈与堆的思考-

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

    C语言之栈和堆(Stack && Heap)的优缺点及其使用区别

    本篇文章主要介绍了什么是栈(Stack) 、什么是堆( Heap),以及栈和堆的优缺点,同时介绍了应该什么时候使用堆和栈,有需要的朋友可以参考下

    java 栈和堆,Java自动管理栈和堆

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

    堆和栈总结

    堆栈(stack),堆(heap) Java堆栈 jvm为每个新创建的线程都分配一个堆栈。堆栈以帧为单位保存线程的状态。jvm对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

    静态区、堆、栈 区别

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它...

    JavaScript实现栈结构Stack过程详解

    数组(Aarray)栈(Stack)链表(Linked List)图(Graph)散列表(Hash)队列(Queue)树(Tree)堆(Heap) 注意:数据结构与算法与语言无关,常见的编程语言都有直接或间接的使用上述常见的数据结构。 1.2.什么是...

    堆和栈区别.pdf

    1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操 作方式类似于数据结构中的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由 OS 回 收 。...

    华为、中兴C.C++笔试面试知识点

    Heap是堆,stack是栈。Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。Stack空间有限,Heap是很大的自由存储区C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。程序在编译期对...

    微软亚洲技术中心的C++面试题

    1.进程和线程的差别。 线程是指进程内的一个执行单元,也是进程内的可调度实体. ...Heap是堆,stack是栈。 Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。 Stack空间有限,Heap是很大的自由存储区

    C++中的栈和堆的区别

    1、栈区(stack)― 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap) ― 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它...

Global site tag (gtag.js) - Google Analytics