Java中的堆和栈

来源:互联网 发布:java遍历list中的对象 编辑:程序博客网 时间:2024/05/16 06:17

1、堆(heap)和栈(stack)的区别与联系

(1)堆和栈都是Java中用来在RAM(Random-Access Memory 随机存取存储器)存放数据的地方,但是与C++不同的地方是,C++对于堆和栈的管理方面,程序员可以直接的设置,但是在Java中是不允许的,而是通过Java本身的机制对堆和栈进行自动管理。
(2)栈相比于堆的优点在于,存取速度快,仅次于CPU中的寄存器。但是,不足的是,存在栈中的数据大小和生命周期是确定的(比如说一个int型的变量,其数据的存储大小是固定的,为32位,其生命周期就是它的作用域)。
(3)堆的优势则在于,他可以动态的分配存储空间,通过一系列的哈希算法换算成一长串数字来表示变量在堆中的“物理地址”。而其生命周期也是不确定的,由Java垃圾回收机制决定,在其使用结束之后某个不确定的时间有Java自动回收释放内存。

2、Java中内存机制——堆内存和栈内存

Java中的内存分为两种,分别为堆内存和栈内存。对应于第一点中的两者。
(1)栈内存
在方法中定义的一些基本的变量(共有8中,即int、short、long、byte、float、double、boolean、char(并没有String)),这种类型的使用方法是通过类似于long a=11L等形式来定义的,我们可以称之为自动变量,而自动变量中存储的即为表面定义的值,而不是值的引用。
这些表面定义的值的数据,其大小长度是固定的,其生命周期也是明确的(即其定义所在的程序块,当程序块退出时,自动变量几倍释放),由于速度的需求,就把他们存储在栈中,另外,栈还有一个另外的重要特殊性,那就是存在栈中的数据可以共享,在这里我就不进行论述了。
当在一个代码块中定义了一个基本变量或对象的引用变量时,Java就会在栈中为这个变量分配空间,当程序块退出时,Java会立即释放掉该变量分配的内存空间,以便其他变量进行使用。
(2)堆内存
堆内存用于存放由new所创建的对象(实例)和数组。并对应的在栈中创建一个引用变量只想该对象&数组的首地址,此时这个引用变量可以理解为该对象的一个别名或者代号。这样就可以在程序中,通过栈中的引用变量来使用对象或数组,有利于提升访问的速度。
在堆中分配的内存,有Java虚拟机自动进行回收。引用变量时普通变量,当超出其作用域时,立即被释放,但是其指向的对象&数组却没有立即被释放。只有当其没有了任何的引用变量指向他们时,他们则变成垃圾,虽然不能再次使用,但是仍然占据着内存,在随后的一个不确定的时间内,被垃圾回收器释放。

3、Java内存分配策略

程序运行时内存分配有三种策略,分别为:静态的、栈式的以及堆式的
(1)静态存储分配

静态存储分配(由static修饰):是指在编译的时候就能确定每个数据目标在运行时的存储空间的需求,因而在编译的时候就给他们分配了固定的空间。静态变量的生命周期一直持续到整个程序的结束。而这种分配策略要求程序运行过程中,不允许更改数据的结构(例如可变数组的存在)。也不允许有嵌套或者递归的结构出现,因为这样都无法计算准确的存储空间需求。
(2)栈式存储分配
栈式存储也被称为动态存储分配,是有一个类似于堆栈的运行栈来实现。和静态存储分配相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的。只有到了运行的时候才中知道。但是规定在运行中进入一个程序的模块时,必须知道该程序模块所需的数据区大小才能够为其分配内存。
(3)堆式存储分配
堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储所需的数据结构的内存分配,比如可变长度可对象实例。堆由大片的可利用空间快或空闲快组成,堆中内存可以按任意顺序分配和释放。




原创粉丝点击