`
ss1
  • 浏览: 79799 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

如何销毁对象

阅读更多

在任何一个面向对象的语言中,这个对象销毁机制都是很重要的。因为如果对象不能够被及时的回收,那么很多没用的对象就仍然会占用内存地址。久而久之,就会导致内存耗竭,从而导致服务器当机。

在这个对象的销毁上,Java语言比其他面向对象的语言更胜一筹。因为其他面向对象的语言,需要在程序代码中手工回收废弃的对象。不过Java语言则不同。在Java语言中拥有一套完整的对象垃圾回收机制。即程序开发人员不需要手工的回收废弃的对象。垃圾回收器将回收无用对象所占用的内存资源。不过这个垃圾回收器并不是万能的,需要结合其他的对象回收方式,才能够最终解决这个对象回收的问题。在Java中,总共有三种方式可以用来解决对象回收的问题,笔者将他们称为三把利剑。

第一把剑:垃圾回收器

垃圾回收器是Java平台中用的最频繁的一种对象销毁方法。垃圾回收器会全程侦测Java应用程序的运行情况。当反先有些对象成为垃圾时,垃圾回收器就会销毁这些对象,并释放这些对象所占用的内存空间。在这里,程序开发人员需要知道,在哪些情况下垃圾回收器会认为这些对象是垃圾对象。通常情况下,如果发生以下两种情况时,系统会认为这些对象是垃圾对象,需要销毁。

一是将一个NULL值赋值给对象。如用户先建立了一个对象str1。对象用完了之后,再利用赋值语句,将NULL值赋值给这个对象str1,即使用str1=NULL的方式将NULL值赋值给这个对象。此时这个对象与内存中对象的存储地址之间就失去了联系。此时内存中的对象就好像成为了一个无主的对象,就会被垃圾回收器销毁。不过这也有例外。如现在同一个对象有两个名字,分别为str1与str2。此时若只是将NULL值赋值给str1,那么内存的这个对象仍然有一个主人,即str2。此时这个对象还暂时不会被垃圾回收器回收。除非在代码中讲这个对象所关联的所有对象名字都赋值为NULL。此时这个对象才变为无主的对象,才会被垃圾回收器回收。在Java中定义自己的工具库

二是对象其超出了作用范围,这个这个对象就被认为是垃圾对象,被被垃圾回收器回收并释放内存。其实对象跟变量一样,其也有作用域。当超过这个作用域的话,跟变量一样,这个对象也就无效了,其他地方不能够再引用这个对象。此时这个对象就是名存实亡了。为此垃圾回收器也把这种超过作用范围的对象当作垃圾对象来处理。所以说,如果程序员要让对象中的某些成员变量或者成员方法一直有效的话,就需要采用static关键字,让其在变量销毁时仍然有效,或则仍然可以调用这些成员变量与成员方法。

另外笔者在这里各位读者一个小的思考题。大家想想看,如果遇到如下这种情况,Java垃圾回收器是否会回收对象?现在笔者先定义两个对象str1,str2。此时在内存中已经为这个两个对象分配了存储空间。然后笔者再利用str2=str1语句,将str1指向的内存地址赋值给str2。此时对象str1、str2就指向同一个内存地址,即代表同一个对象。而原先对象str2指向的对象就变成了一个无主的对象了,对象名str2已经与这个对象失去了联系。在这种情况下,这个对象是否会被当作垃圾对象被销毁呢?给为读者回去可以好好想想这个问题。若能够得出正确的答案,则说明大家对于垃圾回收器已经有了比较透彻的了解。 JDK7更新为Java带来更多模块

第二把利剑:finalize方法

虽然说垃圾回收器已经是一个比较完善的对象销毁机制,但是其并不能够解决Java语言中所有对象的销毁问题。如Java语言平台中,创建对象主要有两种方式,分别为利用NEW关键字来创建(这是对象创建的主要方式)与不适利用NEW关键字来创建。如果Java语言中某些对象不是利用new关键字为对象在内存中分配一块存储区域,那么这种类型的对象就不能够被垃圾回收站回收。即使在代码中将NULL值赋值给这个对象,仍然不能够被垃圾回收器回收。虽然这种对象比较少,但是毕竟存在。为了解决这类对象的回收与内存释放问题,在Java语言中提供了一个finalize的方法。通过这个方法可以显示的让系统回收这个对象。这是一个Object类的方法。通常情况下,这个方法是被声明为protected。程序开发人员在必要的时候,可以在自定的类中定义这个方法。假设现在程序开发人员定义了这个方法,那么在对象销毁时,垃圾回收器会先采用这个方法来销毁对象。并且在下一次垃圾回收动作发生时,最终释放对象的内存。

可见,采用了finalize 方法,虽然可以让这个对象被垃圾回收器回收,但是其原理是不同的。垃圾回收器是先调用这个方法,然后在下次运行这个垃圾回收作业时再释放其占用的内存。另外需要注意的是,这个方法并不一定会保证发生。也就是说,相对来讲,其安全性并没有垃圾回收器那么的高。故在实际创建对象时,最好还是采用new关键字来创建比较安全,也更加的方便。因为在利用New关键字来创建对象时,在代码中不需要加入另外额外的代码。所以从安全性与便利性上来说,笔者都建议采用new方法为对象在内存中分配存储区域,而不建议采用其他的方式。在采用垃圾回收器的时候,其会自动检测对象的状态,而不需要程序员告知。其发现对象超出了作业域范围或者对象被重置为空时,其就会被自动销毁并释放对象所占用的内存,这种方式处理起来相对来说更加的安全与便利。

第三把利剑:利用System.gc方法强制启动垃圾回收器

垃圾回收器其实自动启动的。也就是说,垃圾回收机制起会自动监测垃圾对象,并在适当的时候启动垃圾回收器来销毁对象,释放内存。但是这个垃圾回收器也会有不合作的时候。也就是说,这个垃圾回收器不受程序代码的控制,其具体执行的时间也会不确定,从而导致上面的finalize方法无法执行,某些对象无法及时销毁。为此有时候需要利用代码来强制启动垃圾回收器,来销毁对象。

笔者平时在给一些学员培训时,往往将这个垃圾回收器比喻成医院里的护士。平时的时候,护士会每隔一段时间来进行查房,看看病人有没有什么问题。不过在必要的时候,病人也可以通过警铃来呼叫护士。如当盐水挂完了就可以要求护士来更换盐水。其实这个护士定期查房就好像是垃圾回收器会根据应用程序的运行情况来定时的或者不定时的启动。而这个警铃就好像是这个System.go方法。在有需要的时候,程序开发人员可以在代码中调用这个方法,来强制让护士来病房,即强制启动这个垃圾回收器。采用这个方法,给程序开发人员多了一种主动权,而不需要被动的等着垃圾回收器的启用。有时候,在代码种类利用这个方法不定期或者定期的强制启动垃圾回收器,对及时销毁垃圾对象能够起到一个辅助与保障作用。

分享到:
评论

相关推荐

    【原】unity 不销毁对象的处理

    "不销毁对象的处理"这个话题涉及到如何在游戏运行过程中保持某些对象的状态,而不是在不再需要时销毁它们,然后在需要时重新创建。这通常用于实现持久化数据、避免频繁的实例化和销毁开销,或者维护一些全局的游戏...

    C#创建、销毁对象和继承

    对象的创建和销毁,以及继承,都是面向对象编程的核心概念。接下来,我们将详细探讨这些知识点。 首先,我们来讨论“使用构造方法”。构造方法是类的一个特殊方法,它的主要任务是在创建对象时初始化成员变量。在C#...

    Qt6 QML Book/动态QML/创建和销毁对象示例源码

    在本文中,我们将深入探讨Qt6中的QML技术,特别是关注如何动态地创建和销毁对象。QML是Qt框架提供的一种强大的声明式编程语言,它允许我们构建具有丰富用户界面的应用程序。Qt6版本带来了许多改进和新特性,使得QML...

    JAVA创建和销毁对象的方法

    在Java编程中,创建和销毁对象是至关重要的操作,它们直接影响到程序的性能和内存管理。本文将深入探讨Java中创建对象的几种方法以及对象的销毁。 首先,我们来看看创建对象的基本方式——构造器。构造器是每个类都...

    JAVA中销毁一个对象的方法.doc

    假设现在程序开发职员定义了这个方法,那么在对象销毁时,垃圾回收器会先采用这个方法来销毁对象。并且在下一次垃圾回收动作发生时,终极开释对象的内存。 方法三:利用 System.gc 方法强制启动垃圾回收器 垃圾...

    Unity3D脚本:Object.Destroy 销毁1

    因此,如果你在销毁对象后尝试访问已被销毁的对象,可能会导致错误。为了避免这种情况,可以使用`DestroyImmediate`函数,它会立即从内存中删除对象,但仍然需要谨慎使用,因为这可能影响性能。 此外,当你销毁一个...

    deePool高效的JavaScript对象池

    JavaScript是一种动态类型的编程语言,广泛应用于Web开发,其在处理大量临时对象时,可能会因为频繁创建和销毁对象而导致性能下降。为了解决这个问题,开发者们引入了“对象池”概念, DeePool 就是一个实现这一概念...

    C++程序的生与死,C++中的四种对象(全局对象、局部对象、静态(static)对象、以new方式产生出来的局部对象),以及在C++中有四种方法可以产生一个对象

    - **销毁时机**:当使用`delete`操作符显式销毁对象时,析构函数被调用,并释放之前分配的内存。 #### 对象的创建方式 C++中存在四种创建对象的方法: 1. **在堆栈中创建对象**: - 通过在函数内部声明对象,如`...

    高效的,固定大小的对象池

    对象池的基本思想是通过减少频繁地创建和销毁对象来提升性能。当程序需要对象时,它会从池中获取一个已经初始化好的对象,而不是调用构造函数创建新的。使用完毕后,对象不是被销毁,而是返回到池中,供后续使用。...

    Java中对象的销毁方法分析

    在Java编程语言中,对象的生命周期和销毁是一个关键的概念,它涉及到内存管理和性能优化。下面我们将详细讨论Java中对象的创建、使用以及销毁的过程。 首先,对象的创建通常通过`new`关键字完成,这会在堆内存中...

    C#自定义对象池

    这样可以避免因频繁创建和销毁对象带来的性能损失。 在C#中实现自定义对象池,首先需要定义一个类来存储和管理这些对象。这个类通常包含一个队列或字典来保存对象,以及一些方法如获取对象、归还对象等。以下是一个...

    易语言脚本取对象

    4. 销毁对象:在不再需要对象时,使用`销毁对象`命令释放资源。 易语言脚本取对象的源码分析可以帮助我们更好地理解如何在易语言中使用对象,包括如何动态地创建、获取和操作它们。通过阅读和学习这些源码,开发者...

    对象池简单Demo(资源包)

    1. **减少GC压力**:避免频繁创建和销毁对象,减少垃圾收集器的工作量,提高游戏运行效率。 2. **提高性能**:通过复用对象,减少实例化和销毁的时间开销。 3. **资源管理**:更好地控制对象的生命周期,避免因瞬间...

    游戏对象池例子(兼容智能指针、工厂类)

    游戏开发中的对象池技术是一种优化资源管理的策略,它通过预先创建并缓存一组对象,以避免频繁地创建和销毁对象带来的性能开销。在这个"游戏对象池例子(兼容智能指针、工厂类)"中,我们将探讨如何利用C++实现这种...

    性能优化_对象池

    "对象池"是一种常见的性能优化策略,它针对的是频繁创建和销毁对象所导致的性能损失。本文将深入探讨对象池的概念、工作原理以及在实际应用中的优势和注意事项。 对象池的基本思想是预先创建并维护一组对象,而不是...

    用Dictionary写的对象池

    这种方式可以减少频繁创建和销毁对象带来的性能开销,尤其是在处理大量短生命周期对象的场景下。本文将深入探讨如何使用Dictionary来实现一个简单的对象池,并分析其工作原理、优缺点以及适用场景。 首先,我们来...

    C++对象池源码示例

    对象池是一种优化资源管理的技术,特别是在频繁创建和销毁对象的场景下。本篇将深入探讨对象池的概念、工作原理以及如何在C++中实现对象池。 对象池的基本思想是预先创建并维护一组对象,而不是每当需要时就动态地...

    对象池 射击游戏 子弹的反复生成

    如果频繁地创建和销毁这些子弹,会消耗大量的内存和CPU资源,因为创建和销毁对象的过程是相对昂贵的。对象池的出现就是为了解决这个问题。 对象池的基本思想是预先创建一组对象,并将它们存储在一个集合中,当需要...

    万能对象池【C#实现】

    在编程领域,对象池是一种设计模式,用于管理对象的创建和销毁,以提高程序性能,尤其是在频繁创建和销毁对象的场景下。本文将详细讲解如何使用C#语言实现一个通用的对象池,以及它背后的原理和优势。 首先,理解...

    Unity中对象池插件

    Unity中的对象池是一种优化游戏性能的技术,主要用于管理游戏对象,如敌人、子弹或者特效等,以减少频繁创建和销毁对象带来的开销。对象池插件是实现这一技术的工具,它可以自动化地管理游戏对象的生命周期,提高...

Global site tag (gtag.js) - Google Analytics