在任何一个面向对象的语言中这个对象销毁机制都是很重要的因为如果对象不能够被及时的回收那么很多没用的对象就仍然会占用内存地址久而久之就会导致内存耗竭从而导致服务器当机 在这个对象的销毁上Java语言比其他面向对象的语言更胜一筹因为其他面向对象的语言需要在程序代码中手工回收废弃的对象不过Java语言则不同在Java语言中拥有一套完整的对象垃圾回收机制即程序开发人员不需要手工的回收废弃的对象垃圾回收器将回收无用对象所占用的内存资源不过这个垃圾回收器并不是万能的需要结合其他的对象回收方式才能够最终解决这个对象回收的问题在Java中总共有三种方式可以用来解决对象回收的问题笔者将他们称为三把利剑 第一把剑垃圾回收器 垃圾回收器是Java平台中用的最频繁的一种对象销毁方法垃圾回收器会全程侦测Java应用程序的运行情况当反先有些对象成为垃圾时垃圾回收器就会销毁这些对象并释放这些对象所占用的内存空间在这里程序开发人员需要知道在哪些情况下垃圾回收器会认为这些对象是垃圾对象通常情况下如果发生以下两种情况时系统会认为这些对象是垃圾对象需要销毁 一是将一个NULL值赋值给对象如用户先建立了一个对象str对象用完了之后再利用赋值语句将NULL值赋值给这个对象str即使用str=NULL的方式将NULL值赋值给这个对象此时这个对象与内存中对象的存储地址之间就失去了联系此时内存中的对象就好像成为了一个无主的对象就会被垃圾回收器销毁不过这也有例外如现在同一个对象有两个名字分别为str与str此时若只是将NULL值赋值给str那么内存的这个对象仍然有一个主人即str此时这个对象还暂时不会被垃圾回收器回收除非在代码中讲这个对象所关联的所有对象名字都赋值为NULL此时这个对象才变为无主的对象才会被垃圾回收器回收在Java中定义自己的工具库 二是对象其超出了作用范围这个这个对象就被认为是垃圾对象被被垃圾回收器回收并释放内存其实对象跟变量一样其也有作用域当超过这个作用域的话跟变量一样这个对象也就无效了其他地方不能够再引用这个对象此时这个对象就是名存实亡了为此垃圾回收器也把这种超过作用范围的对象当作垃圾对象来处理所以说如果程序员要让对象中的某些成员变量或者成员方法一直有效的话就需要采用static关键字让其在变量销毁时仍然有效或则仍然可以调用这些成员变量与成员方法 另外笔者在这里各位读者一个小的思考题大家想想看如果遇到如下这种情况Java垃圾回收器是否会回收对象?现在笔者先定义两个对象strstr此时在内存中已经为这个两个对象分配了存储空间然后笔者再利用str=str语句将str指向的内存地址赋值给str此时对象strstr就指向同一个内存地址即代表同一个对象而原先对象str指向的对象就变成了一个无主的对象了对象名str已经与这个对象失去了联系在这种情况下这个对象是否会被当作垃圾对象被销毁呢?给为读者回去可以好好想想这个问题若能够得出正确的答案则说明大家对于垃圾回收器已经有了比较透彻的了解 JDK更新为Java带来更多模块 第二把利剑finalize方法 虽然说垃圾回收器已经是一个比较完善的对象销毁机制但是其并不能够解决Java语言中所有对象的销毁问题如Java语言平台中创建对象主要有两种方式分别为利用NEW关键字来创建(这是对象创建的主要方式)与不适利用NEW关键字来创建如果Java语言中某些对象不是利用new关键字为对象在内存中分配一块存储区域那么这种类型的对象就不能够被垃圾回收站回收即使在代码中将NULL值赋值给这个对象仍然不能够被垃圾回收器回收虽然这种对象比较少但是毕竟存在为了解决这类对象的回收与内存释放问题在Java语言中提供了一个finalize的方法通过这个方法可以显示的让系统回收这个对象这是一个Object类的方法通常情况下这个方法是被声明为protected程序开发人员在必要的时候可以在自定的类中定义这个方法假设现在程序开发人员定义了这个方法那么在对象销毁时垃圾回收器会先采用这个方法来销毁对象并且在下一次垃圾回收动作发生时最终释放对象的内存 可见采用了finalize 方法虽然可以让这个对象被垃圾回收器回收但是其原理是不同的垃圾回收器是先调用这个方法然后在下次运行这个垃圾回收作业时再释放其占用的内存另外需要注意的是这个方法并不一定会保证发生也就是说相对来讲其安全性并没有垃圾回收器那么的高故在实际创建对象时最好还是采用new关键字来创建比较安全也更加的方便因为在利用New关键字来创建对象时在代码中不需要加入另外额外的代码所以从安全性与便利性上来说笔者都建议采用new方法为对象在内存中分配存储区域而不建议采用其他的方式在采用垃圾回收器的时候其会自动检测对象的状态而不需要程序员告知其发现对象超出了作业域范围或者对象被重置为空时其就会被自动销毁并释放对象所占用的内存这种方式处理起来相对来说更加的安全与便利 第三把利剑利用Systemgc方法强制启动垃圾回收器 垃圾回收器其实自动启动的也就是说垃圾回收机制起会自动监测垃圾对象并在适当的时候启动垃圾回收器来销毁对象释放内存但是这个垃圾回收器也会有不合作的时候也就是说这个垃圾回收器不受程序代码的控制其具体执行的时间也会不确定从而导致上面的finalize方法无法执行某些对象无法及时销毁为此有时候需要利用代码来强制启动垃圾回收器来销毁对象 笔者平时在给一些学员培训时往往将这个垃圾回收器比喻成医院里的护士平时的时候护士会每隔一段时间来进行查房看看病人有没有什么问题不过在必要的时候病人也可以通过警铃来呼叫护士如当盐水挂完了就可以要求护士来更换盐水其实这个护士定期查房就好像是垃圾回收器会根据应用程序的运行情况来定时的或者不定时的启动而这个警铃就好像是这个Systemgo方法在有需要的时候程序开发人员可以在代码中调用这个方法来强制让护士来病房即强制启动这个垃圾回收器采用这个方法给程序开发人员多了一种主动权而不需要被动的等着垃圾回收器的启用有时候在代码种类利用这个方法不定期或者定期的强制启动垃圾回收器对及时销毁垃圾对象能够起到一个辅助与保障作用 |