在Java中如何防止类的对象被垃圾收集

Java中的垃圾收集器是自动的,即用户不必手动释放动态分配的已占用内存。垃圾收集器如何决定删除哪个对象?很简单:丢失引用的对象被标记为从堆内存中删除。例如,请看以下代码:

null

// Java code to demonstrate when an object would
// be deleted by the garbage collector
class A {
void f()
{
A x = new A(); /*object created locally
It's scope remains valid till the
termination of this function*/
}
public static void main(String a[])
{
f();
/* function f() terminates,
and hence the object 'x'
too gets collected
by the garbage collector*/
}
}


上面的代码显示,引用变量“x”的作用域仅限于函数“f()”。因此,在上述函数终止后,变量也无法识别。因此,创建的对象会丢失其引用,因此会被垃圾收集器收集。

垃圾收集器收集的对象被收集起来,以便释放堆内存,并在其中分配动态内存。下图解释了Java程序中的不同内存段及其用途:

图片[1]-在Java中如何防止类的对象被垃圾收集-yiteyi-C++库

然而,有时会出现这样的问题: “有没有办法防止垃圾收集器收集对象?”

有几种方法可以使对象在Java中不可删除。下文将对其进行讨论:

通过增加堆内存

Java在一个名为“heap”的分区中将内存分配给它的对象(除了在池中分配内存的String和其他一些特殊对象)。因为堆内存是有限的,所以总是需要释放一些内存来容纳新对象的空间。然而,我们可以在一定程度上通过增加堆大小使对象不可删除。以下jvm命令行参数可以完成任务:

  • Xms
  • xmx

    Xmx指定Java虚拟机(JVM)的最大内存分配池,而Xms指定初始内存分配池。以下是一个例子:

    java -Xms256m -Xmx2048m classfile

    这里,在上面的示例中,您从最初分配的256 MB堆内存开始,它可以扩展到最大2048MB的堆大小。

    这种方法导致垃圾收集器不经常运行,但是当它运行时,完成垃圾收集任务所需的时间将比以前更长。

    通过使用Singleton类

    对于单例类,唯一创建的对象的引用可以存储在静态引用中。由于静态成员存储在类区域(内存段)中,因此它们的生命周期跨越程序的生命周期。以下程序说明了如何执行此操作:

    public class Singleton {
    /* static class member which
    will store the object reference*/
    private static Singleton uniqueInstance;
    private Singleton()
    {
    }
    public static synchronized Singleton getInstance()
    {
    if (uniqueInstance == null ) {
    uniqueInstance = new Singleton();
    }
    return uniqInstance;
    }
    }

    
    

    上面的示例显示,由于对象的引用已被传递到静态变量中,因此它永远不会丢失。因此,直到程序结束,对象才会被删除。然而,唯一的问题是这里只能创建一个对象。

    使用public void finalize()

    Finalize是一个回调方法(JVM调用的方法,而不是用户调用的方法),是在对象上执行的最后一个方法。子类可以重写finalize方法来处理系统资源或执行其他清理。

    如何使用finalize防止垃圾收集?

    可以重写类的finalize方法,以保留即将删除的对象的引用。以下程序演示了如何:

    // Java code to demonstrate how to prevent garbage collection
    // of an object using finalize method
    class A {
    static A y;
    void f()
    {
    A x = new A();
    }
    pubic void finalize()
    {
    y = this ; // Putting the reference id
    // of the current object
    // into the static variable y
    System.out.println("Object reference saved. The object
    won't be collected by the garbage collector");
    }
    public static void main(String a[])
    {
    f(); // function called
    }

    
    

    输出:

    Object reference saved. The object won't be collected by the garbage collector

    如前所述,finalize是在对象上执行的最后一个方法。在上面的程序中,函数“f()”创建了类a的一个局部对象。当函数的调用终止时,变量“x”的作用域也终止,因此被标记为由垃圾收集器收集。但是,在垃圾收集器删除对象之前,请完成运行。

    在“finalize”方法的主体中,可以看到类A“y”的静态成员被分配了当前对象的引用id。因此,将保留要删除的对象的引用id,因此不会删除该对象。

    然而,让一个对象不可删除是有风险的,并且会增加内存泄漏的可能性,这一点非常重要。因此,这样做是不可取的。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享