【问题标题】:Java Performance: When clearing a object is it better to set to null or create a new object.Java 性能:清除对象时最好设置为 null 或创建新对象。
【发布时间】:2011-07-28 15:01:35
【问题描述】:

重复使用一个对象时,是清空数据,还是实例化一个新对象比较好?

   Object a = new Object();
   for(...){
       ...
       a = null;
       **OR**
       a = new Object();
    }

这是我所指的示例:

Customer a = new Customer();
Collection<Customer> data = new ArrayList<Customer>();

        while (rs != null && rs.next()) {   
            a = new Customer();
            a.setCustId(rs.getLong("CUST_ID"));
            a.setPerNo(period);
            a.setName(rs.getString("cust_nm"));

            if(a!= null)
                data.add(a);
        }

我想知道是否

a = new Customer();

是执行此操作的最佳方法,或者是否应该以不同的方式执行此操作以节省内存并获得最佳性能,因为每个循环都有新的客户信息要输入。据我了解,如果您创建一个新客户,您就是创建一个新对象并将 a 指向该新对象。因此,a 指向的旧对象将被垃圾收集器拾取 - 在将其设置为 null 的情况下也是如此。这是正确的理解吗?

【问题讨论】:

  • 您必须为结果集的每一行创建一个新客户,否则您最终会在列表中获得相同的对象,其次数与结果集中的行数相同根据结果​​集中的最后一行设置其属性。也不需要空检查,a 不能为空。
  • 除非在a.setNameif(a!=null) 之间发生了什么,否则if(a!= null) 测试是完全多余的。它会总是通过。

标签: java performance object null new-operator


【解决方案1】:

我更喜欢:

for (...) {
    Object a = new Object();
    ...
}

为什么要让范围比它需要的更大?

同样,除非我需要一个新对象,否则我不会为了它而创建一个。

仅从给出的描述很难说更多 - 如果您能给出一个更完整和更真实的例子,我们也许能够提出更具体的建议。

(请注意,没有迹象表明您要重复使用一个对象,就像重复使用一个变量一样。它们是非常不同的概念。)

编辑:看看你的具体例子,我会这样写:

Collection<Customer> data = new ArrayList<Customer>();

while (rs != null && rs.next()) {   
    Customer a = new Customer();
    a.setCustId(rs.getLong("CUST_ID"));
    a.setPerNo(period);
    a.setName(rs.getString("cust_nm"));

    data.add(a);
}

请注意,这不会创建 任何 Customer 符合垃圾回收条件的对象 - 而您的原始代码在进入循环之前创建 Customer 的实例,然后忽略新的创建对象,而是创建一个新对象并重新分配 a 的值。

【讨论】:

  • 我编辑了我的问题以澄清我想说的话。我可能会误解,但是您的建议如何更有效?我将其理解为定义一个对象 a 然后将其实例化为一个新对象,以便每次循环时都会创建一个新对象而不是修改现有对象。 - 提前感谢您的帮助。
  • @Brad:你没有定义一个对象 a,你是在声明一个变量 a。这不是效率问题——而是更简洁的代码。从效率的角度来看,在循环内部还是外部声明变量都没有关系。
【解决方案2】:

在需要的地方实例化对象。不要在你没有的地方。在分析器告诉您之前,不要担心这种级别的优化。

编辑:鉴于您更新的答案,读者会更清楚地声明变量并在循环内实例化您的 Customer 对象,正如 Jon 建议的那样。至于你的性能和垃圾回收问题,需要improve your grasp of the basic language concepts

【讨论】:

  • 这是迄今为止最好的答案。
【解决方案3】:

在您明确想要“停止”引用对象并且不这样做会导致实际内存泄漏的特殊情况下,需要显式 NULLing 引用。例如,您可以查看支持数组的 List 实现,其中 NULL 数组槽以避免指向不再使用的引用/对象。

【讨论】:

    【解决方案4】:

    我认为您的困惑来自不了解对象是通过引用传递的。如果您来自 C 背景,请了解在 Java 中,Customer a = new Customer(); 实际上做了类似

    Customer* a = (Customer*) malloc (sizeof(Customer));
    initializeCustomer (a); //the constructor initializes the state of the object.
    

    由于添加到列表中的每个客户实际上都需要新内存,因此无法避免为循环的每次迭代创建一个新的客户对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 2015-05-12
      • 1970-01-01
      • 2012-03-08
      • 2020-09-13
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多