4.实例变量和类变量内存分配
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实例变量和类变量内存分配
Java向程序员许下一个承诺:无需关心内存回收,java提供了优秀的垃圾回收机制来回收已经分配的内存。大部分开发者肆无忌惮的挥霍着java程序的内存分配,从而造成java程序的运行效率低下!
java内存管理分为两方面:
1,内存的分配:指创建java对象时,jvm为该对象在堆内存中所分配的内存空间。
2,内存的回收:指当该java对象失去引用,变成垃圾时,jvm的垃圾回收机制自动清理该对象,并回收该对象占用的内存。
jvm的垃圾回收机制由一条后台线程完成。不断分配内存使得系统中内存减少,从而降低程序运行性能。大量分配内存的回收使得垃圾回收负担加重,降低程序运行性能。
一,实例变量和类变量(静态变量)
java程序的变量大体可分为成员变量和局部变量。
其中局部变量有3类:形参、方法内的局部变量、代码块内的局部变量。
局部变量被存储在方法的栈内存中,生存周期随方法或代码块的结束而消亡。
在类内定义的变量被称为成员变量。没使用static修饰的称为成员变量,用static修饰的称为静态变量或类变量。
1.1实例变量和类变量的属性
在同一个jvm中,每个类只对应一个Class对象,但每个类可以创建多个java对象。
【其实类也是一个对象,所有类都是Class实例,每个类初始化后,系统都会为该类创建一个对应的Class实例,程序可以通过反射来获取某个类所对应的Class实例(Person.class 或Class.forName(“Person”))】
因此同一个jvm中的一个类的类变量只需要一块内存空间;但对实例变量而言,该类每创建一次实例,就需要为该实例变量分配一块内存空间。
非静态函数需要通过对象调用,静态函数既可以通过类名调用,也可以通过对象调用,其实用对象调用静态函数,底层还是用类名调用来实现的!
1.2实例变量的初始化时机
对实例变量而言,它属于java对象本身,每次创建java对象时都需要为实例变量分配内存空间,并执行初始化。
从语法角度来看,程序可在三个地方对实例变量执行初始化:
1. 定义实例变量时指定初始值
2. 非静态初始块中对实例变量指定初始值
3. 构造器中对实例变量指定初始值
其中第1、2种方式比第三种方式更早执行,第1、2种方式执行的顺序与他们在源程序中的排列位置相关,在前面的先执行。
每当程序指定构造器来创建java对象时,该构造器必然会获得执行机会。与此同时,该类所包含的非静态初始化块和定义实例变量指定初始值也将会获得执行机会,并且总是在构造器执行之前获得执行。
1.class TestDemo {
2.public TestDemo(){
3. System.out.println("这是一个构造函数");
4. System.out.println("ser的值为"+ser);
5. }
6. {//这是一个构造代码块
7. System.out.println("这是一个构造代码块");
8. ser=4;
9. }
10.double ser=3.0;
11.public static void main(String[] args) {
12. TestDemo test=new TestDemo();
13. System.out.println("...........");
14. TestDemo test2=new TestDemo();
15. }
16.}
1.
/*运行结果:2.这是一个构造代码块
3.这是一个构造函数
4. ser的值为3.0
5. ...........
6.这是一个构造代码块
7.这是一个构造函数
8. ser的值为3.0
9.*/
定义实例变量时指定的初始值,初始块中为实例变量指定初始值的语句的地位是平等的,当经过编译器处理后,他们都将被提取到构造器中。也就是说,对于类定义中的语句:
double ser = 3.0
实际上会被分成如下2次执行:
1.double ser ;创建java对象时系统根据该语句为该对象分配内存
2.ser =
3.0;赋值动作会被提取到构造器中执行!
实际上,ser所指定的初始化值每次都会被3.0覆盖,因为定义变量时指定的初始值和初始化块中指定的初始值的执行顺序,与它们在源程序中的排列顺序相同。
1.3类变量的初始化时机
类变量属于类本身,只有当jvm加载该类时才会为该类的类变量分配内存空间,并执行初始化。
从程序运行角度看,JVM对一个java类只初始化一次,因此java程序每运行一次,系统只为类变量分配一次内存空间,执行一次初始化。
从语法角度看,程序可在2个地方对类变量执行初始化:
1.定义类变量时指定初始值
2.静态初始化块中对类变量指定初始值。
两种方式的执行顺序与他们在源程序中排列顺序相同。同样,程序先为所有类变量分配内存空间,再按源代码中两种方法的排列顺序执行相应的初始化值。
总而言之,对象的初始化过程为:
1.在栈内建立变量
2.类加载进内存
3.执行静态代码块
4.在堆内存中开辟空间,分配内存地址
5.在堆内存中建立对象的特有属性,并进行默认初始化
6.对属性进行显示初始化
7.对对象进行构造代码块初始化
8.对对象进行对应的构造函数初始化
9.将内存地址赋给栈内存中的变量