黑马程序员——java小结_003_堆和栈

来源:互联网 发布:淘宝国际物流订单运费 编辑:程序博客网 时间:2024/05/19 06:47

------- android培训、java培训、期待与您交流! ----------

       上一小节提到java中的堆和栈,这一小节就稍微总结一下吧.

       java把内存分成堆内存和栈内存两种.

       堆内存用来存放new创建的对象和数组.

       在堆内存分配中,由java虚拟机(JVM)垃圾自动回收器来管理.在堆中产生了一个数组或者对象后,还可以在栈中定义一个引用变量,它指向数组或对象在堆内存中的首地址,其实就是相当于给堆内存中的对象或数组起一个别名放在栈中,以后可以通过栈来访问堆中的对象或数组.

       栈内存用来存放一些基本的类型的变量和对象的引用变量.

       当一段代码块中定义一个变量时,java就在战中为这个变量分配内存空间,当超过此变量的作用域时,java会释放掉为该内存分配的内存空间.

      

       栈中的变量指向堆内存中的变量,其实可以理解为java中的指针.

 

       需要注意的是:

       加入你定义了数组或对象,相应的也定义了对他们的引用变量.

       那么当程序运行到引用比那两作用域之外时,引用变量就会被释放.

       但是,

       程序即使运行到使用new创建数组和对象的语句所在代码块之外,数组和对象所占有的堆内存也不会被释放.

       数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。

       这个也是java比较占内存的主要原因.

 

       简单来说堆主要用来存放对象,栈主要用来执行程序.

 

       JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

    我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的. 

  从Java的这种分配机制来看,堆栈又可以这样理解:堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。 

  每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享. Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。


另外说一下静态存储分配;

        静态存储分配是指在编译时就能确定每个数据目标在运行时刻的存储空间需求,因而在编译时就可以给他们分配固定的内存空间.这种分配策略要求程序代码中不允许有可变数据结构(比如可变数组)的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间需求. 


------- android培训、java培训、期待与您交流! ----------


0 0
原创粉丝点击