上一篇:带你“找对象”--Java内存分析 | 带你学《Java面向对象编程》之二
【本节目标】
通过阅读本章,你将通过多组实例从内存上深度了解通过对象声明、方法调用等方法进行引用传递的原理,并深刻理解引用为何会产生内存垃圾以及GC机制的相关内容。
3.1 引用传递分析
类本身属于引用数据类型,既然是引用数据类型,那么就牵扯到内存的引用传递,所谓的引用传递的本质:同一块堆内存的空间可以被不同的栈内存所指向,也可以更换指向。
范例:定义一个引用传递的分析程序
public class JavaDemo {
public static void main(String args[]) {
Person per1 = new Person() ; //声明并实例化对象
per1.name = “张三” ;
per1.age = 18 ;
Person per2 = per1 ; //引用传递
per2.age =80 ;
per1.tell() ; //进行方法的调用
}
}
图一 内存分析结果一
图二 运行结果一
这个时候的引用传递是直接在主方法之中定义的,也可以通过方法实现引用传递
范例:利用方法实现引用传递处理
public class JavaDemo {
public static void main(String args[]) {
Person per = new Person() ; //声明并实例化对象
per.name = “张三” ;
per.age = 18 ;
change(per) ; //等价于:Person temp = per ;
per.tell() ; //进行方法的调用
}
public static void change(Person temp){
temp.age = 80 ;
}
}
图三 运行结果二
图四 内存分析结果二
与之前的差别最大的地方在于,此时的程序是将Person类的实例化对象(内存地址、数值)传递到了change方法之中,由于传递的是一个Person类型,那么change()方法接收的也是Person类型。
引用传递可以发生在方法上,这个时候一定要观察方法的参数类型,同时也要观察方法的执行过程。
3.2 引用与垃圾产生分析
经过一系列分析后,所有的引用传递的本质就是一场堆内存的调戏游戏。但是对于引用传递,如果处理不当,那么也会造成垃圾的产生,那么本次将针对于垃圾产生的原因进行简单分析。
范例:定义一个要分析的程序
public class JavaDemo {
public static void main(String args[]) {
Person per1 = new Person() ; //声明并实例化对象
Person per2 = new Person() ;
per1.name = “张三” ;
per1.age = 18 ;
per2.name = “李四” ;
per2.age =19 ;
per2 = per1 ; //引用传递
per2.age =80 ;
per1.tell() ; //进行方法的调用
}
}
图五 运行结果三
此时已经明确发生了引用传递,并且也成功的完成了引用传递的处理操作,但是下面来观察一下其内存的分配与处理操作。
一个栈内存只能够保存有一个一堆内存的地址数据,如果发生更改,则之前的地址数据将从此栈内存中彻底消失。下面来看看它的内存分析结果。
图六 内存分析结果三
所谓的垃圾空间指的就是没有任何栈内存所指向的堆内存空间,所有的垃圾将被GC(Garbage Collector、垃圾收集器)不定期进行回收并且释放无用内存空间,但是如果垃圾过多,一定将影响到GC的处理性能,从而降低整体的程序性能。那么在实际开发之中,对于垃圾的产生应该越少越好。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学