导航:首页 > 编程语言 > java栈顶

java栈顶

发布时间:2024-01-15 13:46:28

1. 堆栈、静态区、堆这三者有什么区别呢,在C语言或java中有区别吗

堆和栈的区别
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int a = 0; 全局初始化区
char *p1; 全局未初始化区
main()
{
int b; 栈
char s[] = "abc"; 栈
char *p2; 栈
char *p3 = "123456"; 123456\0在常量区,p3在栈上。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

二、堆和栈的理论知识
2.1申请方式
stack:
由系统自动分配。 例如,声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间
heap:
需要程序员自己申请,并指明大小,在c中malloc函数
如p1 = (char *)malloc(10);
在C++中用new运算符
如p2 = (char *)malloc(10);
但是注意p1、p2本身是在栈中的。

2.2
申请后系统的响应
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,
会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。

2.3申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

2.4申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.
另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

2.5堆和栈中的存储内容
栈: 在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

2.6存取效率的比较

char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void main()
{
char a = 1;
char c[] = "1234567890";
char *p ="1234567890";
a = c[1];
a = p[1];
return;
}
对应的汇编代码
10: a = c[1];
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]
0040106A 88 4D FC mov byte ptr [ebp-4],cl
11: a = p[1];
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]
00401070 8A 42 01 mov al,byte ptr [edx+1]
00401073 88 45 FC mov byte ptr [ebp-4],al
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。

2.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

2. java堆栈问题~~~

堆栈是一种数据结构,特点是堆栈中的数据先进后出,或者说后进先出。你可以想象堆栈是个子弹夹,先压入的子弹放在弹夹下面,后压入的子弹会在弹夹的上面,打枪或者卸子弹的时候先出上面的子弹,下面的子弹才能出来。

堆栈会有一个量来标识栈顶,也就是标识出堆栈里最后放进去的数据在什么位置。堆栈可以进行的操作最基本的是两个:一个进栈(push)一个出栈(pop),也有叫压入弹出的。进栈的时候要判断栈是否已满,已满的堆栈不能进栈,弹夹满了,子弹肯定压不进去了。出栈的时候要判断栈是否为空,弹夹空了要卸子弹肯定是卸不出来的。

3. JAVA中队列和栈的区别

队列(Queue):是限定只能在表的一端进行插入和在另一端进行删除操作的线性表;

栈(Stack):是限定只能在表的一端进行插入和删除操作的线性表。

区别如下:

一、规则不同

1. 队列:先进先出(First In First Out)FIFO

2. 栈:先进后出(First In Last Out )FILO

二、对插入和删除操作的限定不同

1. 队列:只能在表的一端进行插入,并在表的另一端进行删除;

2. 栈:只能在表的一端插入和删除。

三、遍历数据速度不同

1.
队列:基于地址指针进行遍历,而且可以从头部或者尾部进行遍历,但不能同时遍历,无需开辟空间,因为在遍历的过程中不影响数据结构,所以遍历速度要快;

2.
栈:只能从顶部取数据,也就是说最先进入栈底的,需要遍历整个栈才能取出来,而且在遍历数据的同时需要为数据开辟临时空间,保持数据在遍历前的一致性。

4. java中,栈和堆分别是什么创建的最好详细点。。

栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
Java 的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
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, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。

String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。

String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。
因此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。

java中内存分配策略及堆和栈的比较
2.1 内存分配策略
按照编译原理的观点,程序运行时的内存分配有三种策略,分别是静态的,栈式的,和堆式的.
静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求.
栈式存储分配也可称为动态存储分配,是由一个类似于堆栈的运行栈来实现的.和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到运行的时候才能够知道,但是规定在运行中进入一个程序模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存.和我们在数据结构所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。
静态存储分配要求在编译时能知道所有变量的存储要求,栈式存储分配要求在过程的入口处必须知道所有的存储要求,而堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例.堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放.

2.2 堆和栈的比较
上面的定义从编译原理的教材中总结而来,除静态存储分配之外,都显得很呆板和难以理解,下面撇开静态存储分配,集中比较堆和栈:
从堆和栈的功能和作用来通俗的比较,堆主要用来存放对象的,栈主要是用来执行程序的.而这种不同又主要是由于堆和栈的特点决定的:
编程中,例如C/C++中,所有的方法调用都是通过栈来进行的,所有的局部变量,形式参数都是从栈中分配内存空间的。实际上也不是什么分配,只是从栈顶向上用就行,就好像工厂中的传送带(conveyor belt)一样,Stack Pointer会自动指引你到放东西的位置,你所要做的只是把东西放下来就行.退出函数的时候,修改栈指针就可以把栈中的内容销毁.这样的模式速度最快, 当然要用来运行程序了.需要注意的是,在分配的时候,比如为一个即将要调用的程序模块分配数据区时,应事先知道这个数据区的大小,也就说是虽然分配是在程序运行时进行的,但是分配的大小多少是确定的,不变的,而这个"大小多少"是在编译时确定的,不是在运行时.
堆是应用程序在运行的时候请求操作系统分配给自己内存,由于从操作系统管理的内存分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少存储空间,也不必知道存储的数据要在堆里停留多长的时间,因此,用堆保存数据时会得到更大的灵活性。事实上,面向对象的多态性,堆内存分配是必不可少的,因为多态变量所需的存储空间只有在运行时创建了对象之后才能确定.在C++中,要求创建一个对象时,只需用 new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存.当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的缺点,人的缺点往往也是人的优点(晕~).

2.3 JVM中的堆和栈
JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的.
从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。
每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。

5. java语言中用LinkList实现堆栈

栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。

LinkedList数据结构是一种双向的链式结构,每一个对象除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素,和数组的顺序存储结构(如:ArrayList)相比,插入和删除比较方便,但速度会慢一些。

栈的定义

栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。

(1)通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。

(2)当表中没有元素时称为空栈。

(3)栈为后进先出(Last In First Out)的线性表,简称为LIFO表。

栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中"最新"的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。

实现代码:

package com.weisou.dataStruct;

import java.util.LinkedList;

@SuppressWarnings("unchecked")

public class MyStack {

LinkedList linkList = new LinkedList<Object>();

public void push(Object object) {

linkList.addFirst(object);

}

public boolean isEmpty() {

return linkList.isEmpty();

}

public void clear() {

linkList.clear();

}

// 移除并返回此列表的第一个元素

public Object pop() {

if (!linkList.isEmpty())

return linkList.removeFirst();

return "栈内无元素";

}

public int getSize() {

return linkList.size();

}

public static void main(String[] args) {

MyStack myStack = new MyStack();

myStack.push(2);

myStack.push(3);

myStack.push(4);

System.out.println(myStack.pop());

System.out.println(myStack.pop());

}

}

队列定义

队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表

(1)允许删除的一端称为队头(Front)。

(2)允许插入的一端称为队尾(Rear)。

(3)当队列中没有元素时称为空队列。

(4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。

实现代码:

package com.weisou.dataStruct;

import java.util.LinkedList;

/**

*

* @author gf

* @date 2009-11-13

*/

public class MyQueue {

LinkedList linkedList = new LinkedList();

//队尾插

public void put(Object o){

linkedList.addLast(o);

//队头取 取完并删除

public Object get(){

if(!linkedList.isEmpty())

return linkedList.removeFirst();

else

return "";

}

public boolean isEmpty(){

return linkedList.isEmpty();

}

public int size(){

return linkedList.size();

}

public void clear(){

linkedList.clear();

}

/**

* @param args

*/

public static void main(String[] args) {

MyQueue myQueue= new MyQueue();

myQueue.put(1);

myQueue.put(2);

myQueue.put(3);

System.out.println(myQueue.get());

}

}

6. 堆和栈的区别

Java把记忆体分成两种,一种叫做栈记忆体,一种叫做堆记忆体。栈和堆有什么区别呢?下面我带你了解一下。

在函式中定义的一些基本型别的变数和物件的引用变数都在函式的栈记忆体中分配。

当在一段程式码块定义一个变数时,Java就在栈中为这个变数分配记忆体空间,当超过变数的作用域后,Java会自动释放掉为该变数所分配的记忆体空间,该记忆体空间可以立即被另作他用。

堆记忆体用来存放由new建立的物件和阵列。

java中记忆体分配策略及堆和栈的比较

1 记忆体分配策略

按照编译原理的观点,程式执行时的记忆体分配有三种策略,分别是静态的,栈式的,和堆式的.

喊迟静态储存分配是指在编译时就能确定每个资料目标在执行时刻的储存空间需求,因而在编译时就可以给他们分配固定的记忆体空间.这种分配策略要求程式程式码中不允许有可变资料结构比如可变阵列的存在,也不允许有巢状或者递回的结构出现,因为它们都会导致编译程式无法计算准确的储存空间需求.

栈式储存分配也可称为动态储存分配,是由一个类似于堆叠的执行栈来实现的.和静态储存分配相反,在栈式储存方案中,程式对资料区的需求在编译时是完全未知的,只有到执行的时候才能够知道,但是规定搜渗圆在执行中进入一个程式模组时,必须知道该程式模组所需的资料区大小才能够为其分配记忆体.和我们在资料结构所熟知的栈一样,栈式储存分配按照先进后出的原则进行分配。

静态储存分配要求在编译时能知道所有变数的储存要求,栈式储存分配要求在过程的处必须知道所有的储存要求,而堆式储存分配则专门负责在编译时或执行时模组处都无法确定储存要求的资料结构的记忆体分配,比如可变长度串和物件例项.堆由大片的可利用块或空闲块组成,堆中的记忆体可以按照任意顺序分配和释放.

2 堆和栈的比较

上面的定义从编译原理的教材中总结而来,除静态储存分配之外,都显得很呆板和难以理解,下面撇开静态储存分配,集中比较堆和栈:

从堆和栈的功能和作用来通俗的比较,堆主要用来存放物件的,栈主要是用来执行程式的.而这种不同又主要是由于堆和栈的特点决定的:

在程式设计中,例如C/C++中,所有的方法呼叫都是通过栈来进行的,所有的区域性变数,形式引数都是从栈中分配记忆体空间的。实际上也不是什么分配,只是从栈顶向上用就行,就好像工厂中的传送带conveyor belt一样,Stack Pointer会自动指引你到放东西的位置,你所要做的只是把东西放下来就行.退出函式的时候,修改栈指标就可以把栈中的内容销毁.这样的模式速度最快, 当然要用来执行程式了.

需要注意的是,在分配的时候,比如为一个即将要呼叫的程式模组分配资料区时,应事先知道这个资料区的大小,也就说是虽然分配是在程式执行时进行的,但是分配的大小多少是确定的,不变的,而这个"大世塌小多少"是在编译时确定的,不是在执行时.

堆是应用程式在执行的时候请求作业系统分配给自己记忆体,由于从作业系统管理的记忆体分配,所以在分配和销毁时都要占用时间,因此用堆的效率非常低.但是堆的优点在于,编译器不必知道要从堆里分配多少储存空间,也不必知道储存的资料要在堆里停留多长的时间,因此,用堆储存资料时会得到更大的灵活性。

事实上,面向物件的多型性,堆记忆体分配是必不可少的,因为多型变数所需的储存空间只有在执行时建立了物件之后才能确定.在C++中,要求建立一个物件时,只需用 new命令编制相关的程式码即可。执行这些程式码时,会在堆里自动进行资料的储存.当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配储存空间时会花掉更长的时间!这也正是导致我们刚才所说的效率低的原因,看来列宁同志说的好,人的优点往往也是人的缺点,人的缺点往往也是人的优点晕~.

3 JVM中的堆和栈

JVM是基于堆叠的虚拟机器.JVM为每个新建立的执行绪都分配一个堆叠.也就是说,对于一个Java程式来说,它的执行就是通过对堆叠的操作来完成的。堆叠以帧为单位储存执行绪的状态。JVM对堆叠只进行两种操作:以帧为单位的压栈和出栈操作。

我们知道,某个执行绪正在执行的方法称为此执行绪的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当执行绪启用一个Java方法,JVM就会线上程的 Java堆叠里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来储存引数,区域性变数,中间计算过程和其他资料.这个帧在这里和编译原理中的活动纪录的概念是差不多的.

从Java的这种分配机制来看,堆叠又可以这样理解:堆叠Stack是作业系统在建立某个程序时或者执行绪在支援多执行绪的作业系统中是执行绪为这个执行绪建立的储存区域,该区域具有先进后出的特性。

每一个Java应用都唯一对应一个JVM例项,每一个例项唯一对应一个堆。应用程式在执行中所建立的所有类例项或阵列都放在这个堆中,并由应用所有的执行绪共享.跟C/C++不同,Java中分配堆记忆体是自动初始化的。Java中所有物件的储存空间都是在堆中分配的,但是这个物件的引用却是在堆叠中分配,也就是说在建立一个物件时从两个地方都分配记忆体,在堆中分配的记忆体实际建立这个物件,而在堆叠中分配的记忆体只是一个指向这个堆物件的指标引用而已。

4.栈与堆都是Java用来在Ram中存放资料的地方

与C++不同,Java自动管理栈和堆,程式设计师不能直接地设定栈或堆。

Java的堆是一个执行时资料区,类的物件从中分配空间。这些物件通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程式程式码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配记忆体大小,生存期也不必事先告诉编译器,因为它是在执行时动态分配记忆体的,Java的垃圾收集器会自动收走这些不再使用的资料。但缺点是,由于要在执行时动态分配记忆体,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于暂存器,栈资料可以共享。但缺点是,存在栈中的资料大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本型别的变数,int, short, long, byte, float, double, boolean, char和物件控制代码。

栈有一个很重要的特殊性,就是存在栈中的资料可以共享。假设我们同时定义:

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, 它是由编译器完成的,它有利于节省空间。而一个物件引用变数修改了这个物件的内部状态,会影响到另一个物件引用变数 。

阅读全文

与java栈顶相关的资料

热点内容
手机文件夹删除又出现怎么解决 浏览:285
php时间段分析 浏览:213
redisjava类 浏览:911
剪力墙错开部分钢筋是否加密 浏览:477
linux字符设备驱动程序 浏览:57
全排列算法java 浏览:465
中国银行app转账电子回单在哪里 浏览:51
操作简单的程序员 浏览:600
数值积分算法求pi 浏览:18
按钮怎么连命令方块 浏览:909
房贷还清后不解压能贷款吗 浏览:36
程序员哄老婆开心技术 浏览:672
oracle自动备份压缩文件 浏览:855
遵义人字形加密网带 浏览:255
宁波人社在哪里下载app 浏览:92
好哒商户app下载在哪里下载 浏览:609
广发兑星巴克是在app哪里操作 浏览:783
linuxgetline 浏览:215
app的悬浮窗权限在哪里设置 浏览:686
51单片机定时器溢出标志 浏览:373