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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李爱霞 黑马帝   /  2011-12-30 15:41  /  2930 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。

堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

回复 使用道具 举报
  java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。

堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。

回复 使用道具 举报
本帖最后由 李爱霞 于 2011-12-30 17:50 编辑

请教一下,关于java中对堆和栈他们对实例变量,局部变量,静态变量,以及全局变量,他们分别在堆和栈是怎么存储的,以及存储的生命周期

评分

参与人数 1技术分 +1 收起 理由
吴上储 + 1

查看全部评分

5 个回复

倒序浏览
栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中。
堆:存放用new产生的数据。
静态域:存放在对象中用static定义的静态成员。
常量池:存放常量。
当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。
数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。
静态变量是类相关的变量,所以他的生命周期是从这个类被声明,到这个类彻底被垃圾回收机制彻底回收才会被销毁。
静态变量生命周期就是类的开始和销毁

评分

参与人数 1技术分 +1 收起 理由
杨强 + 1

查看全部评分

回复 使用道具 举报
付星 黑马帝 2011-12-30 16:49:54
报纸
对于堆和栈来说不是用实例变量,局部变量,静态变量,以及全局变量区别的
如果是基本数据类型是存储在栈里
如果是复杂类型一般存储在堆里
静态变量是类加载就存储了
局部变量只是大括号中有效
全局变量如果是类的成员变量就看是什么类型了
实体变量如里没有谁引用JVM会自动回收
回复 使用道具 举报
看到这个问题之后,我就打算要打很长的一段代码了,因为这几天我正在看这些东西,强烈建议看一下《深入Java虚拟机》
下面引用书里讲到这部分的知识:看完下面的估计不用具体回答你的问题,就可以自己总结出来了。
(可能有打错字的现象,莫怪。。。)

每一个Java虚拟机都有一个类装载器子系统,(看张孝祥老师的视频也会看到),它根据给定的全限定名来装入类型(类

或接口)。同样,没一个Java虚拟机都有一个执行引擎,它负责执行那些包含在被装载类的方法中的指令。
当Java虚拟机运行一个程序时,它需要内存来存储很多东西,例如:字节码,从已装载的class文件中得到其他信息,程

序创建的对象,传递给方法的参数,返回值,局部变量,以及运算的中间结果等等。Java虚拟机把这些东西都组织到几个

“运行时数据区”中,以便于管理。
尽管这些“运行时数据区”都会以某种形式存在于没一个Java虚拟机实现中,但是规范对它们的描述十分抽象。这些运行

时数据区结构上的细节,大多数都是由具体实现的设计者决定。
不同的虚拟机实现可能具有很不同的内存限制,有的实现可能有大量的内存可用,有的可能只有很少。有的实现可以利用

虚拟内存,有的则不能。规范本身对“运行时数据区”只有抽象描述,这就使得Java虚拟机可以很容易的在各种计算机和

设备上实现。
某些运行时数据区是由程序中所有线程共享的,还有一些则只能由一个线程拥有。每个Java虚拟机实例都是有一个方法区

和以及一个堆,它们由该虚拟机实例中所有线程共享的。当虚拟机装载一个class文件时,它会从这个class文件包含的二

进制数据中解析类型信息。然后,它把这些类型信息放到方法区中。当程序运行时,虚拟机会把所有该程序在运行时创建

的对象都放到堆中。
当每一个新线程被创建时,它都将得到它自己的PC寄存器(程序计数器)以及一个Java栈。如果线程正在执行的是一个

Java方法(非本地方法),那么PC寄存器的值将总是指示下一条将被执行的指令,而它的Java栈则总是存储该线程中Java

方法的调用状态——包括它的局部变量,被调用时传来的参数,它的返回值,以及运算的中间结果等等。而本地方法调用

的状态,则是以某种依赖于具体实现的方式存储在本地方法栈中,也可能是在寄存器或者其他某些与特定实现相关的内存

区中。
Java栈是由许多栈帧(stack frame)或者说帧(frame)组成的,一个栈帧包含一个Java方法调用的状态。当线程调用一

个Java方法时,虚拟机压入一个新的栈帧到该线程的Java栈中,当该方法返回时,这个栈帧被从Java栈中弹出并抛弃。
Java虚拟机没有寄存器,其指令集使用Java栈来存储中间数据。这样设计的原因是为了保持虚拟机的指令集尽量紧凑,同

时也便于Java虚拟机在那些只有很少通用寄存器的平台上实现。
Java虚拟机为没一个线程创建的内存区是私有的,任何线程都不能访问另一个线程的PC寄存器或者Java栈。


Java虚拟机是通过数据类型来执行计算的。数据类型可以分为:基本类型和引用类型
基本类型的变量持有原始值,而引用类型的变量持有引用值。术语“引用值”指的是对某个对象的引用,而不是该对象本

身。于此相对,原始值则是真正的原始数据。(在毕老师的视频中String中有提到类似问题)


这上面要注意的就是“类型”这个术语,有很多的解释,一般情况下,类型会暗示为类和接口。方法区中存放的是二进制

文件中的类型信息,堆中存放的是运行是程序创建的对象。
这里还有必要提一下Java虚拟机中的引用类型。Java虚拟机中的引用类型统称为“引用”,有三种引用类型:类类型,接

口类型以及数组类型,他们的值都是对动态创建对象的引用。类类型的值是对类实例的引用;数组类型的值是对数组对象

的引用,在Java虚拟机中,数组是个真正的对象;而接口类型的值,则是对实现了该接口的某个类实例的引用。还有一种

特殊的引用值就是null,它表示变量没有引用任何对象。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马