黑马程序员技术交流社区

标题: 关于java内存空间的一些总结及细节问题 [打印本页]

作者: 夏儒日    时间: 2012-7-4 16:29
标题: 关于java内存空间的一些总结及细节问题
     在老毕的视频中老毕经常要求强调我们要会话程序的内存图,张老师的书中也经常需要画内存图,可见Java内存分配对我们更好的学习理解有很大帮助.故在此本人总结一些关于Java内存分配及管理的知识,希望对大家学习有所帮助.
     Java内存分配与管理师Java的核心技术之一,通常Java内存分配时会涉及到以下区域:
     1.栈:存放基本类型的数据和对象的引用,但对象本身不放在栈中,而是存放在堆中.
     2.堆:存放用new产生的对象和数组
   3.方法区:存放类信息、静态变量、final常量、属性和方法信息,包括常量池      
            常量池:存放常量,包含基本类型和对象型(如String和数组) 的常量,还包含一些文本形式出现的符号引用,如类和接口的全限定名/方法和名称的描述符等;
     4.静态区:存放在对象中用static定义的静态成员;
     5.寄存器:我们在程序中无法控制.

     总结得不全及错漏的地方,望有心人提出及更改,共同进步.

     我的问题是:为什么有栈内存和堆内存之分,以及栈和堆的区别.
   
作者: 赵倩倩    时间: 2012-7-4 16:42
     栈。在RAM区域,可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时,Java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动指针。因此影响了程序的灵活性,所以尽管有些Java数据要保存在栈里,但Java对象并不放到其中。
   堆。也在RAM区域其中保存了Java对象。和栈不同,编译器不用事先知道要从堆里分配多少存储空间,也不知道存储的数据要在堆里停留多长的时间所以用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码就行。执行这些代码时,会在堆里自动进行数据的保存。为达到这种灵活性,所付出的代价就是在堆里分配存储空间时会花掉更长的时间!

作者: 赵庆礼    时间: 2012-7-5 23:33
Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java 就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用。

  堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或者对象,引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。

这也是Java比较占内存的原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2