`
syyixin
  • 浏览: 36601 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Java基础之栈堆简介

    博客分类:
  • Java
阅读更多

 

(stack)与堆(heap)是两种数据结构,其数据项均按序排列,即只能在一端对数据项进行插入、删除等操作。其中栈一般由编译器自动分配释放,用来存放方法的参数值、局部变量等数据,遵循先进后出(First-In/Last-Out)原则;堆则一般运行时分配,用来存放New出来的对象等数据,由JVM自动回收,遵循先进先出(First-In/First-Out)原则。

 

栈堆均存在缓存机制,其中栈用的是一级缓存,局部变量等被调用时分配内存,调用完毕则空间立即被释放;栈使用的是二级缓A存,其生命周期由Java虚拟机JVM的垃圾回收算法自动回收。很显然,因为缓存机制不同栈中局部变量等数据调用速度会比较快,而堆中对象等数据生命周期不确定且属于运行时动态分配,故调用速度效率相对较低。

 

这里我做一个不太妥当的比喻以帮助大家理解:栈是呼吸系统,进入呼吸系统的主要是空气,空气更新比较快;堆是消化系统,一个馒头一只苹果地进去,经过消化系统较长时间的消化后才被排出,并且早上吃的鸡蛋一定比晚上吃的粥先排出来,如下示意图所示:


 

 

举个具体的例子,我们知道 intbyteshortfloat等基本数据类型定义的时候是以“数据类型变量名 = 变量值;”的方式进行定义,如int x=1;。编译器分析这句话的时候首先在栈中创建一个变量为x的引用,然后在栈中进行查找,看有没有值为1的地址存在;如果存在则将引用指向该地址,否则开辟存放1的地址并将变量x指向该地址,这里假设指向的地址为0x0001。需要注意的是,这些基本数据类型是值类型,传递的是值而非引用。即如果定义一个新的变量y=1;编译器就是寻找值为1,因为之前有x的引用指向的值为1,所以找到了,那么栈中创建变量y的引用并指向x指向的地址,亦即xy两个变量指向同一个地址0x0001。这时候我们改变x的值,比如x=3;,因为栈里面找不到值为3的地址,所以栈开辟新的空间来存这个值,比如这个空间地址是0x0002,这时候x的值确实变化了,但x 的变化并没有影响y的值的变化,y变量的引用指向的仍旧是值为1的地址0x0001。栈的内部处理流程及结构如下图所示:



 

 
 

 

 

Java中通过new()关键字来显式告诉编译器这些new出来的对象要放在堆中,并且是运行时才能动态创建,其内部运行机制和结构与栈类似,栈弄明白了堆自然而然也就变得明了。

 

        

 

作者:忆辛,公历201522日17时09分写于羊城,发表在iteye网站,未经作者书面许可,任何单位或个人不得转载、复制本文的全部或部分内容。

 

  • 大小: 39.3 KB
  • 大小: 32.6 KB
  • 大小: 6.7 KB
4
2
分享到:
评论
4 楼 syyixin 2015-02-03  
谢谢指出,写错了;栈一级堆二级
3 楼 tomgxf 2015-02-03  
栈1级缓存,堆2级缓存。
2 楼 huyinghuying 2015-02-03  
“栈使用的是二级缓存” 是 “堆使用的是二级缓存”
1 楼 huyinghuying 2015-02-03  
"栈使用的是二级缓A存" 应该是“堆栈使用的是二级缓A存”

相关推荐

Global site tag (gtag.js) - Google Analytics