博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 堆栈内存分配
阅读量:6037 次
发布时间:2019-06-20

本文共 1897 字,大约阅读时间需要 6 分钟。

很多人在Java的书籍中看到过很多关于堆和栈内存的教程以及参考说明, 但是很难解释什么是程序的堆内存以及栈内存

一: Java 堆内存空间

Java程序运行时使用java Heap 内存为对象以及JRE类分配内存, 不论我们在何时创建何种类型的对象, 他总是在堆内存中创建的

Java 垃圾收集器运行在堆内容空间, 释放那些没有任何引用的对象所使用的内存。 在堆内存空间创建的任何对象都具有全局访问权限, 并且可以从程序的任何位置引用

二: Java 栈内存空间

Java 栈内存空间用于执行线程, 栈内存始终遵循LIFO(Last-in-first-out) 顺序, 每当一个方法被执行, 会在栈内存中创建一个新的block 用于保存在函数中定义的基本数据类型变量以及对象的引用变量

当方法结束时, this block 改变它的状态为未使用并且可用于执行下一个方法

堆内存大小与堆内存相比非常少。

三: Java程序中的堆和堆栈内存

通过一个简单的程序来理解堆 栈内存的使用情况

/** * Created by huanjulu on 12/10/17. */public class HeapStackTestMemory {    public static void main(String[] args) { //Line 1        int i = 1; //Line 2        Object obj = new Object(); //Line 3        HeapStackTestMemory mem = new HeapStackTestMemory(); //Line 4        mem.foo(obj);  //Line 5    }  //Line 9    private void foo(Object param) {  //Line 6        String str = param.toString();  //Line 7        System.out.println(str);    } //Line 8}复制代码

参考上面的java 程序, 下图显示了stack Heap 内存空间的使用情况

我们来看看执行程序的步骤。

  • 一旦我们开始运行程序, 它会把所有的运行时类加载到堆内存空间, 在 Line 1 行找到main() 方法, Java Runtime 创建由main() 方法线程使用的栈内存空间
  • 在第二行 我们创建了原始数据类型的局部变量, 所以它将被存储在main() 方法的栈内存空间
  • 在第3行我们创建了一个Object 类型的对象, 所以它被创建在Heap 堆内存空间中 并且 Stack 栈内存空间包含对它的引用, 当我们在第4行中创建Memory 对象时, 会发生类似的过程
  • 现在我们在第5行调用foo() 方法, 此时会在stack 栈创建一个block 供foo() 方法使用
  • Java 是通过值传递, 在第6行, 会在foo() 栈中创建一个对Object 对象的新的引用
  • 在第7行 , 一个string 类型的对象被创建, 此时 会在foo() 栈内存中创建它的一个引用 str
  • foo() 方法在第8行执行完毕, 此时, 程序会释放stack 栈内存中为foo() 方法分配的栈内存空间
  • 在第9行, main() 方法执行完毕, 为main()方法创建的堆栈内存被销毁, 此时 这个java 程序结束运行, Java Runtime 会释放所有的内存

 

三: Java Heap Difference with Stack Memory Space

基于上述的说明, 可以很容易的总结出堆栈内存的以下差异

1, 堆内存属于java 应用程序所使用, 栈内存属于线程所私有的, 它的生命周期与线程相同

2, 不论何时创建一个对象, 它总是存储在堆内存空间 并且栈内存空间包含对它的引用 . 栈内存空间只包含方法原始数据类型局部变量以及堆空间中对象的引用变量
3, 在堆中的对象可以全局访问, 栈内存空间属于线程所私有
4, jvm 栈内存结构管理较为简单, 遵循LIFO 的原则, 堆空间内存管理较为复杂 , 细分为:新生代和老年代 etc..
5, 栈内存生命周期短暂, 而堆内存伴随整个用用程序的生命周期
6, 二者抛出异常的方式, 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常, 堆内存抛出OutOfMemoryError异常

转载地址:http://gjlhx.baihongyu.com/

你可能感兴趣的文章
ubuntu linux下建立stm32开发环境: GCC安装以及工程Makefile建立
查看>>
记录锁
查看>>
JSONObject与JSONArray的使用
查看>>
[SQL Server] 数据库日志文件自动增长导致连接超时的分析
查看>>
【常见Web应用安全问题】---6、Script source code disclosure
查看>>
<html:form>标签
查看>>
除了《一无所有》,我一无所有
查看>>
每日英语:China Seeks to Calm Anxiety Over Rice
查看>>
C++中struct和class的区别 [转]
查看>>
C++ ofstream和ifstream详细用法
查看>>
【G-BLASTN 1.0正式发布】
查看>>
Mysql 连接查询 Mysql支持的连接查询有哪些
查看>>
wireshark tcp 协议分析 z
查看>>
Need a code of lazy load for div--reference
查看>>
HTable和HTablePool使用注意事项
查看>>
如何使用JW Player来播放Flash并隐藏控制按钮和自定义播放完成后执行的JS
查看>>
04 http协议模拟登陆发帖
查看>>
Codeforces Round #298 (Div. 2) B. Covered Path 物理题/暴力枚举
查看>>
百度地图定位地址为空
查看>>
云计算设计模式(五)——计算资源整合模式
查看>>