A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 孙娜 中级黑马   /  2013-2-24 19:11  /  5574 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 孙娜 于 2013-2-26 10:50 编辑

为什么局部变量是存在栈内存中的?是不是只要知道局部变量是存在栈内存中的就可以了,哪位可以更深入的讲解一下,谢谢

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 鼓励一下

查看全部评分

6 个回复

倒序浏览
栈上的变量是从高地址向低地址分配的,因为记住操作系统的程序放在内存的最高地址区块,然后我们申请栈时,就从操作系统区块以下的相对高地址开始向低地址生长;否则,如果从低地址向高地址分配,如果程序需要很多内存,一旦踏入操作系统区块,系统就崩了,所以这样是为了保护操作系统。
回复 使用道具 举报
当启用一个线程时,JVM就为他分配一个Java栈,栈是以帧为单位保存当前线程的运行状态。
每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,这个帧用来存储参数、局部变量、中间运算结果等等。
所以局部变量就被压进栈中了

评分

参与人数 1黑马币 +6 收起 理由
陈丽莉 + 6

查看全部评分

回复 使用道具 举报
楼上威武..

其实局部变量也可以算是临时变量了.  
栈内存内部的数据变动的量很大.
局部变量在栈内存中就是用过了就释放.  存活周期短.
而对内存较局部变量算是"长驻"了. 存活周期长.

评分

参与人数 1黑马币 +6 收起 理由
陈丽莉 + 6

查看全部评分

回复 使用道具 举报
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。


程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器。不做重点解释。

Java 虚拟机栈,
它的生命周期与线程相同。虚拟机栈描述的是 Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame①)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。  经常有人把 Java 内存区分为堆内存(Heap)和栈内存(Stack),这种分法比较粗糙,Java 内存区域的划分实际上远比这复杂。这种划分方式的流行只能说明大多数程序员最关注的、与对象内存分配关系最密切的内存区域是这两块。其中所指的“堆”在后面会专门讲述,而所指的“栈”就是现在讲的虚拟机栈,或者说是虚拟机栈中的局部变量表部分。
局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不等同于对象本身,根据不同的虚拟机实现,它可能是一个指向对象起始地址的引用指针,也可能指向一个代表对象的句柄或者其他与此对象相关的位置)和 returnAddress 类型(指向了一条字节码指令的地址)。


Java 堆
Java 堆(Java Heap)是 Java 虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在 Java 虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配,但是随着 JIT 编译器的发展与逃逸分析技术的逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上也渐渐变得不是那么“绝对”了。

方法区
方法区(Method Area)与 Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。



对象访问
Java 栈、Java 堆、方法区这三个最重要内存区域之间的关联关系,
如下面的这句代码:  


Object obj = new Object();  


假设这句代码出现在方法体中,那“Object obj”这部分的语义将会反映到 Java 栈的本地变量表中,作为一个 reference 类型数据出现。而“new Object()”这部分的语义将会反映到 Java 堆中,形成一块存储了 Object 类型所有实例数据值(Instance Data,对象中各个实例字段的数据)的结构化内存,根据具体类型以及虚拟机实现的对象内存布局(Object Memory Layout)的不同,这块内存的长度是不固定的。另外,在 Java 堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

慢慢看吧,这是 我在 深入理解Java虚拟机 这本书中看到的。

评分

参与人数 1黑马币 +6 收起 理由
陈丽莉 + 6

查看全部评分

回复 使用道具 举报
感觉主要两个原因
1)栈的存取速度比堆要快
2)可以及时释放内存

评分

参与人数 1黑马币 +6 收起 理由
陈丽莉 + 6

查看全部评分

回复 使用道具 举报
函数内局部变量的存储单元在栈上创建,函数执行结束时自动被释放。栈内存分配运算内置于处理器的指令集中,效率高,但容量有限
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马