Java 性能:清除对象时,最好设置为 null 还是创建一个新对象。

发布于 2024-11-26 19:54:16 字数 830 浏览 2 评论 0原文

当重复使用一个对象时,是通过将其设置为null来清除数据更好,还是实例化一个新对象更好?

   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 的情况相同。这是正确的理解吗?

When using an object repeatedly, is it better to clear the data by setting it to null, or instantiate a new object?

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

Here is the example I'm referring to:

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);
        }

I'm wondering whether the

a = new Customer();

is the best way to do this or if it should be done differently to save on memory and for optimum performance, because each loop has new customer information to put in. From my understanding, if you create a new customer you're creating a new object and pointing a to that new object. So the old object a was pointing to will get picked up by the garbage collector - same in the case of setting it to null. Is this a correct understanding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

音盲 2024-12-03 19:54:17

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

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

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

I think your confusion comes from not understanding that objects are passed by reference. If you're coming from a C background, understand that in Java, Customer a = new Customer(); actually does something like

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

Since you actually need new memory for each customer you add to your list, you cannot avoid creating a new Customer object for each iteration of the loop.

你爱我像她 2024-12-03 19:54:16

我更喜欢:

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 的值。

I would prefer:

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

Why make the scope any greater than it needs to be?

Likewise, unless I needed a new object, I wouldn't create one for the sake of it.

It's hard to say much more from just the description given though - if you can give a more complete and real-world example, we may be able to make more concrete recommendations.

(Note that there's no indication that you want to use an object repeatedly, so much as using a variable repeatedly. They're very different concepts.)

EDIT: Looking at your specific example, I'd write it like this:

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);
}

Note that this doesn't create any Customer objects which are eligible for garbage collection - whereas your original code creates an instance of Customer before entering the loop, and then ignores the newly created object, instead creating a new one and reassigning a's value.

别念他 2024-12-03 19:54:16

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

编辑:根据您更新的答案,读者可以更清楚地声明变量并在循环内实例化您的 Customer 对象,正如 Jon 建议的那样。至于你的性能和垃圾收集问题,你需要提高对基本语言的掌握概念

Instantiate objects where you need them. Don't where you don't. And don't worry about this level of optimization until a profiler tells you to.

Edit: Given your updated answer, it would be clearer to readers to declare the variable and instantiate your Customer objects inside the loop, as Jon recommended. As to your performance and garbage collection questions, you need to improve your grasp of the basic language concepts.

儭儭莪哋寶赑 2024-12-03 19:54:16

对于特殊情况,需要显式对引用进行 NULL 处理,在这种情况下,您明确希望“停止”引用某个对象,而如果不这样做将导致实际的内存泄漏。作为示例,您可以查看数组支持的 List 实现,其中 NULL 数组槽以避免指向不再使用的引用/对象。

Explicitly NULLing references is required for special cases wherein you explicitly want to "stop" referring to an object and failure to do so would result in an actual memory leak. As an example, you can have a look at the array backed List implementation which NULLs array slots to avoid pointing to references/objects which are no longer used.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文