随笔-10  评论-11  文章-20  trackbacks-0
        java程序运行的关键是栈和堆。它们是把内存形象的分为栈内存和堆内存,栈是运行时的单位,堆时存储单位。栈内存中存储着句柄,堆内存中存储着具体内容。而且在实例化的时候建立句柄对内容的指向关系,程序运行,首先访问句柄,然后调用具体内容。

例:在new完一个具name和age两个属性的P后栈和堆得关系如下图所示:

         那么为什么要有这种设计原理呢?从软件设计的角度看,栈代表了处理逻辑,而堆代表了数据。这样分开,使得处理逻辑更为清晰,分而治之的思想。这种隔离、模块化的思想在软件设计的方方面面都有体现。        堆与栈分离,使得堆中的内容可以被多个栈共享(也可以理解为多个线程访问同一个对象)这种共享的收益是很多的,一方面这种共享提供了一种有效的数据交互(共享内存),另一方面,堆中的共享常量和缓存可以被所有栈访问,节省了空间。        栈因为运行时的需要,比如保存系统运行的上下文,需要进行地址段的划分。由于栈只能向上增长,因此就会限制住栈存储内容的能力。而堆不同,堆中的对象是可以根据需要动态增长的,因此栈和堆的拆分,使得动态增长成为可能,相应栈中只需记录堆中的一个地址即可。        Java 的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。        堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。        栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

例:在new完两个具name和age两个属性的P1和P2后,内存会发生如下变化:

当执行P2 = P1时,指向将会发生变化:

当先执行P1.name = "price";P1.age=43后堆内存改变,但是执行完P2.name = "soap";P2.age = 23后堆内存则发生如下改变,原先P2所指的那块堆内存则成为垃圾,又GC进行回收:

posted on 2010-10-12 22:33 Soap MacTavish 阅读(1770) 评论(1)  编辑  收藏

评论:
# re: 对Java中栈(stack)和堆(heap)的一点小认识 2015-12-27 20:22 | wuwuwuwu
句柄  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: