Java中堆和栈的区别(结合示例程序分析各自存储情况)
2017-05-04 10:50
375 查看
在Java语言中,堆与栈都是内存中存放数据的地方。变量分为基本数据类型和引用类型,基本数据类型的变量(例如int、short、byte、double、float、boolean以及char等)以及对象的引用变量,其内存都分配在栈上,变量出了作用域就会自动释放,而引用类型的变量,其内存分配在堆上或者常量池(例如字符串常量和基本数据类型常量)中,需要通过new等方式进行创建。
具体而言,栈内存主要用来存放基本数据类型与引用变量。栈内存的管理是通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系,每当有函数调用时,都会通过压栈方式创建新的栈帧,每当函数调用结束后都会通过弹栈的方式释放栈帧。
堆内存用来存放运行时创建的对象。一般来讲,通过new关键字创建出来的对象都存放在堆内存中。由于JVM是基于堆栈的虚拟机,而每个Java程序都运行在一个单独的JVM实例上,因此这些线程之间会共享堆内存,鉴于此,多线程在访问堆中的数据时需要对数据进行同步。
在C++中,堆内存的管理都是由开发人员来负责的,也就是说,开发人员在堆中申请内存,当不再使用时,也必须由开发人员来完成堆内存的释放工作。而在Java语言中,这个内存释放的工作由垃圾回收器来负责执行,开发人员只需要申请所需的对空间而不需要考虑释放的问题。
在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中这个变量就变成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。这就是Java中引用的用法。
从堆和栈的功能以及作用来比较,堆主要用来存放对象,栈主要用来执行程序。相较于堆,栈的存取速度更快,但栈的大小和生存期必须是确定的,因此缺乏一定的灵活性。而堆却可以在运行时动态地分配内存,生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢。
堆和栈的存储如下例所示:
由于i为基本数据类型的局部变量,因此它存储在栈空间中,而r为对象的引用变量,因此也被存储在栈空间中;实际的对象存储在堆空间中,当main()方法退出后,存储在栈中的i和r通过压栈和弹栈操作将会在栈中被回收,而存储在堆中的对象将会由垃圾回收器来自动回收。
具体而言,栈内存主要用来存放基本数据类型与引用变量。栈内存的管理是通过压栈和弹栈操作来完成的,以栈帧为基本单位来管理程序的调用关系,每当有函数调用时,都会通过压栈方式创建新的栈帧,每当函数调用结束后都会通过弹栈的方式释放栈帧。
堆内存用来存放运行时创建的对象。一般来讲,通过new关键字创建出来的对象都存放在堆内存中。由于JVM是基于堆栈的虚拟机,而每个Java程序都运行在一个单独的JVM实例上,因此这些线程之间会共享堆内存,鉴于此,多线程在访问堆中的数据时需要对数据进行同步。
在C++中,堆内存的管理都是由开发人员来负责的,也就是说,开发人员在堆中申请内存,当不再使用时,也必须由开发人员来完成堆内存的释放工作。而在Java语言中,这个内存释放的工作由垃圾回收器来负责执行,开发人员只需要申请所需的对空间而不需要考虑释放的问题。
在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中这个变量就变成了数组或对象的引用变量。引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。这就是Java中引用的用法。
从堆和栈的功能以及作用来比较,堆主要用来存放对象,栈主要用来执行程序。相较于堆,栈的存取速度更快,但栈的大小和生存期必须是确定的,因此缺乏一定的灵活性。而堆却可以在运行时动态地分配内存,生存期不用提前告诉编译器,但这也导致了其存取速度的缓慢。
堆和栈的存储如下例所示:
package com.js.csdn; /** * 堆和栈的存储 * @author JiangShuai * */ class Rectangle{ private int width; private int length; public Rectangle(int width,int length){ this.width = width; this.length = length; } } public class Test { public static void main(String[] args) { int i = 1; Rectangle r = new Rectangle(3, 5); } }在上述程序进入main()方法后,数据的存储关系如下图所示:
由于i为基本数据类型的局部变量,因此它存储在栈空间中,而r为对象的引用变量,因此也被存储在栈空间中;实际的对象存储在堆空间中,当main()方法退出后,存储在栈中的i和r通过压栈和弹栈操作将会在栈中被回收,而存储在堆中的对象将会由垃圾回收器来自动回收。
相关文章推荐
- 内存监控方法之——Jmap结合Memory Analyzer,分析java程序是否存在内存泄漏
- java 集合 之 链表和线性表以及ArrayList的各方法的介绍及示例 及 ArrayList与LinkedList的区别分析 及 ArrayList与Array(数组)的区别
- java中ArrayList 、LinkList的区别分析---程序中设比较时间
- 实验 3.1.5 查看代码中各数据存储位置 示例程序: mem_add.c 1. 在自己的机器上运行示例程序。 2. 分析实验结果,图示程序运行时各数据位置。
- dos窗口下能编译java程序,但不能执行情况分析
- 【Java学习笔记之十七】Java中普通代码块,构造代码块,静态代码块区别及代码示例分析
- 利用java自带的性能分析工具visualvm来分析java程序运行情况
- 用MAT分析JAVA程序运行时的内存使用情况
- java程序中数据存储与示例详解
- Java程序开发中的内存分配情况分析
- Win32程序函数调用时堆栈变化情况分析
- ASP.NET结合存储过程写的通用搜索分页程序
- 写 Java 程序最容易犯的 21 种错误实例分析
- ASP.NET结合存储过程写的通用搜索分页程序(转)
- ASP.NET结合存储过程写的通用搜索分页程序
- 写 Java 程序最容易犯的 21 种错误实例分析
- ASP.NET结合存储过程写的通用搜索分页程序
- ASP.NET结合存储过程写的通用搜索分页程序
- 写 Java 程序最容易犯的 21 种错误实例分析
- 一个用Dijkstra算法实现的路由算法的java程序——9 图信息文件示例