首页 > 解决方案 > 减少返回数组的方法的Java垃圾收集?

问题描述

对象 A 具有方法 B(),并且在应用程序的大部分生命周期中都存在。B 调用对象 C 的方法 D()。D() 返回一个包含 x 个 MyData 对象的数组。MyData 可能是 POD(plain old data)/PDS(passive data structure)或更多,但 MyData 可以通过调用方法或设置字段来重用;它的身份或功能在施工或其他方面并不是一成不变的。

目前 B() 的定义如下:

class A {
  public B() {
    MyData[] amydata = c.D( 5 );
       :
       :
  }
}

目前 D() 的定义如下:

MyData[] D( int iRows ) {

    MyData[] amydata = new MyData[ iRows ];

    for ( int i = 0; i < iRows; i++ ) {

        if ( no more data )
            return amydata;

        amydata [ i ] = new MyData();

        // calculate or fill in MyData structure.
    }

    return amydata;
}

A 将总是,或者很长一段时间(例如,直到用户重新配置它)要求相同数量的行,即使数据会有所不同。

那么如果我让调用者传入数组引用怎么办:

class A {
  int iRequestSize = 5;
  int iResultSize;
  MyData[] amydata = new MyData[ iRequestSize ];

  public B() {
    iResultSize = c.D( iRequestSize, amydata );
       :
       :
    // use up to iResultSize even though array is potentially bigger.
  }
}

// returns number of rows actually used
int D( int iRowsMax, MyData[] amydata ) {

    for ( int i = 0; i < iRowsMax; i++ ) {

        if ( no more data )
            return i;

        if ( amydata [ i ] == null )
            amydata [ i ] = new MyData();

        // calculate or fill in MyData structure.
    }

    return iRowsMax;
}

我是一个 C++ 人,刚接触 Java,但似乎假设 MyData 可以像这样回收,第二个版本应该避免创建和复制 MyData,以及消除垃圾收集?

标签: javaperformancegarbage-collection

解决方案


我会说第二种变体更糟。

在第一个变体amydata中,只要方法B()退出,它所引用的所有对象都可以被垃圾收集(假设 B 不存储对amydata其他地方的引用。)

在第二个变体amydata中,只要实例存在,就不能被垃圾收集A

考虑第一次调用D()它返回 5 个对MyData对象的引用,但在随后的调用中它不再返回行的情况。在第一个变体中,amydata数组和 5 个引用的MyData对象可以在B()返回后立即被垃圾收集。但是在第二个变体中,无论是amydata数组还是MyData通过它引用的 5 个对象都不能被垃圾收集——可能永远不会在应用程序的整个运行时进行。

请记住:Java 垃圾收集器针对许多短期对象进行了优化


推荐阅读