Java笔记-内存管理(一)

来源:互联网 发布:日语培训 知乎 编辑:程序博客网 时间:2024/05/17 04:14



            JVM会将申请的内存从逻辑上划分为三个区域:堆、栈、方法区。这三个区域分别用于存储不同的数据。 

      堆内存

       对象存储在堆中

JVM在其内存空间开辟了一个称为“堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象。请看如下代码:

  1. Person c = new Pserson ()

其内存分布如图– 1所示:

图- 1

从图示1中可以看到右侧的堆内存,new Person()所创建的对象在堆中分配,同时成员变量亦在此分配,并赋初始值为零。引用类型变量c在栈内存中分配,其中保存的数据,为对象在堆内存中的地址信息,假设对象在堆内存的地址为40DF,则c中保存的即是40DF。


PS:对象和成员变量存储于堆内存中。


栈内存


栈用于存放方法中的局部变量

JVM在其内存空间开辟一个称为”栈”的存储空间,这部分空间用于存储程序运行时在方法中声明的所有的局部变量,例如,在main方法中有如下代码:

  1. Person c = new Person ( )
  2. int num = 5

其内存分配如图– 2 所示:

图- 2

说明:方法中的变量即为局部变量,是在栈内存中分配,若变量为值类型,则在栈中存储的就是该变量的值。若变量为引用类型,则在栈中存储的是堆中对象的地址。


         PS:栈用于存放方法中的局部变量、参数等数据。


方法区

方法区用于存放类的信息

方法区用于存放类的信息,Java程序运行时,首先会通过类装载器载入类文件的字节码信息,经过解析后将其装入方法区。类的各种信息(包括方法)都在方法区存储,看如下代码:

  1. Person c = new Person()

程序在执行这句话时,Person类首先被装载到JVM的方法区,其中包括类的基本信息和方法定义等,如下图– 3 所示:

图- 3

通过图示可以看出,在方法区中,包含Person类的字节码文件,及类的基本信息及方法drop等。


局部变量的生命周期

一个运行的Java程序从开始到结束会有多次方法的调用。JVM会为每一个方法的调用在栈中分配一个对应的空间,这个空间称为该方法的栈帧。一个栈帧对应一个正在调用中的方法,栈帧中存储了该方法的参数、局部变量等数据。当某一个方法调用完成后,其对应的栈帧将被清除,局部变量即失效。


成员变量的生命周期

当声明好对象之后,对该对象(堆中的Person)的访问需要依靠引用变量(栈中的c),那么当一个对象没有任何引用时,该对象被视为废弃的对象,属于被回收的范围,同时该对象中的所有成员变量也随之被回收。

可以这样认为,成员变量的生命周期为:从对象在堆中创建开始到对象从堆中被回收结束。

请看如下的代码,演示了对象不再被引用:

  1. Person c = new Person();
  2. c = null

当将c赋值为null时,表示c不再指向刚刚分配的对象空间,此时成员变量失效。


        

成员变量和局部变量

成员变量与局部变量的差别如下:

局部变量:

1) 定义在方法中;

2) 没有默认值,必须自行设定初始值;

3) 方法被调用时,存在栈中,方法调用结束时局部变量从栈中清除;

成员变量:

1) 定义在类中,方法外;

2) 由系统设定默认初始值,可以不显式初始化;

3) 所在类被实例化后,存在堆中,对象被回收时,成员变量失效;

0 0
原创粉丝点击