Java基础:初始化及垃圾清理
初始化
对象初始化
假设存在Dog类
- 即使没有显式地使用 static 关键字,构造器实际上也是静态方法。所以,当首次创建 Dog 类型的对象或是首次访问 Dog 类的静态方法或属性时,Java 解释器必须在类路径中查找,以定位 Dog.class。
- 当加载完 Dog.class 后(后面会学到,这将创建一个 Class 对象),有关静态初始化的所有动作都会执行。因此,静态初始化只会在首次加载 Class 对象时初始化一次。
- 当用 new Dog() 创建对象时,首先会在堆上为 Dog 对象分配足够的存储空间。
- 分配的存储空间首先会被清零,即会将 Dog 对象中的所有基本类型数据设置为默认值(数字会被置为 0,布尔型和字符型也相同),引用被置为 null。
- 执行所有出现在字段定义处的初始化动作。
- 执行构造器。你将会在”复用”这一章看到,这可能会牵涉到很多动作,尤其当涉及继承的时候。
注:静态初始化只有在使用到对应的类时(在必要时),才会初始化,如果没有用到,则不会初始化
数组初始化
数组并非基本类型,获取的只是它的一个引用(已分配空间),但是还没有给数组对象本身分配空间,那么就需要初始化数组。
对象的重载
重载本质就是让相同的方法表达不同的意思。Java不能通过一个方法就能表达出所有的意思,但是冗余很多方法就显得很不合理,那么,使用重载就是最佳的解决方案。尤其是构造器的重载。
每个重载的方法都有独一无二的参数列表,这是区分重载方法的关键。
如果是基本类型作为参数的方法的重载,如果传入的基本类型大于参数类型,那么必须要进行向下转型,不然就会报错。
垃圾清理
垃圾清理,顾名思义,就是需要我们将内存中不需要的对象的空间进行释放。
垃圾回收器只知道如何释放用 new 创建的对象的内存,那么,不是通过new来创建的,那么应该怎么清理?为了处理这种情况,出现了finalize()方法。
finalize方法
finalize的作用
通过某种创建对象方式之外的方式为对象分配了存储空间,可以使用finalize来释放其内存,但是,Java中并不存在这种情况。所以,这个情况只有在使用本地方法的发送
本地方法:一种用 Java 语言调用非Java语言代码的形式,目前只支持C/C++
finalize的流程
- 对象在初始化的过程中会判断是否重写了finalize,方法是判断两个字段标志has_finalizer_flag和RegisterFinalizersAtInit。
- 如果重写了finalize,那就把当前对象注册到FinalizerThread的ReferenceQueue队列中。注册之后的对象就叫做Finalizer。方法是调用register_finalizer函数。此时java虚拟机一看当前有这个对象的引用,于是就不进行垃圾回收了。
- 对象开始被调用,FinalizerThread线程负责从ReferenceQueue队列中获取Finalizer对象。开始执行finalize方法,在执行之前,这个对象一直在堆中。
- 对象执行完毕之后,将这个Finalizer对象从队列中移除,java虚拟机一看对象没有引用了,就进行垃圾回收了。
finalize的问题
- 并不能保证垃圾会被清理
- 如果需要清理的对象过多,内存消耗就十分庞大。也就是在第三步时,这个对象含有finalize,进入了队列但一直没有被调用的这段时间,会一直占用内存
Java虚拟机垃圾清理
自适应模式
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 我做梦的博客!
评论

