【问题标题】:Java - Creating new object in method VS declaring it as class memberJava - 在方法 VS 中创建新对象并将其声明为类成员
【发布时间】:2018-09-26 00:58:05
【问题描述】:

假设我们有一个方法可以从ListView 中删除所有项目,然后添加带有用户指定文本的Label:(以标签为例,任何对象都可以 em>)

示例 A 保留较小的变量范围,但在每次方法调用时创建一个新对象:

public void populateListView() {
   listView.getItems().clear();
   Label label = new Label("some string from user");
   listView.getItems().add(label);
}

示例 B 具有更广泛的变量范围,但对象仅在类加载时创建一次。此外,不是创建新的Label,而是使用相同的Label 引用。

public class MyClass{
    private Label label = new Label();

    public void populateListView() {
        listView.getItems().clear();
        label.setText("some string from user");
        listView.getItems().add(label);
    }
}

我们可以看到,在示例 A 中,第一行清除了 listView 的所有对象引用。

这是否意味着,在新的方法调用中,在前一个方法调用中创建的Label 将被垃圾回收(以及多快)?

换句话说,考虑到我们多次调用每个方法,示例 B 在内存分配方面会更有效吗?如果是,请考虑“始终保持最小范围”应该选择哪个示例以及为什么?

【问题讨论】:

  • 1.- 是的,它会在某个时候被 GC。 2.- 是的
  • “有多快?” 这取决于很多因素。垃圾收集器有不同的策略可供选择,它还取决于可用/已用内存...
  • 我会使用第一种方法,只是为了保持最佳的可读性。除非你有数千个标签,否则我不确定这种优化是否值得
  • JavaFX 是一个围绕扩展 Webkit 引擎的外观。这些对象与您的应用程序的性能完全无关。昂贵的部分是 DOM 树以及引擎在非 Java 端所做的事情。标签就是标签,无论您是用新对象还是现有对象来描述它。
  • 好吧,它努力抽象出实现细节,但是你看到了所有的迹象,比如开始显示场景后的有限修改能力,所有典型的(对于 Java 的)定制方式都不是工作,但相反,必须仅使用 CSS 设置所有样式。理论上,API 允许其他后端实现,但基本属性保持不变;你看到的前端课程不是辛苦的工作……

标签: java performance memory javafx jvm


【解决方案1】:

应避免过早的优化,因为它会降低代码质量。
此外,如果您有内存问题,则很少有可能是主要原因,因为 Label 不是一个沉重的对象(对象本身,而不是它的渲染)并且您不会在方法中创建数千个它.
所以让垃圾收集器完成它的工作并通过将变量的范围缩小到严格要求来保持清晰的代码(示例 A)。

如果稍后您在运行时遇到内存问题,请分析您的应用程序(例如使用 JVisualVM)以找出罪魁祸首(很可能不是这个问题)。

【讨论】:

  • 感谢您的意见。总而言之,我应该始终遵循示例 A 的方法,除非对象很大或可用内存非常有限?
  • 大体上是的。并不是说我会注意对象是否“巨大”,不仅因为我想节省内存,而且因为分配/收集一个大对象可能需要时间,因此在 CPU 消耗方面也有成本。
猜你喜欢
  • 2019-05-26
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2021-04-19
  • 2016-12-09
相关资源
最近更新 更多