Java 重用(静态?)对象作为临时对象以提高性能

标签 java android static allocation temporary

我需要在模拟循环中经常调用具有多个方法的类的方法。

其中一些方法需要访问临时对象以在其中存储信息。离开方法后,不再需要存储的数据。 例如:

Class class {      
  method1() {
        ...
        SomeObject temp = new SomeObject();
       ...
  }

  method2() {
        ...
        SomeObject temp = new SomeObject();
        SomeObject temp2 = new SomeObject();
        ...
  }
}

我需要尽可能地优化。最昂贵的(可移除的)问题是发生了太多的分配。 我认为最好不要每次都为这些对象分配所需的空间,所以我想保留它们。

以静态方式存储它们是否更有效? 喜欢:

Class class {
  private (static?) SomeObject temp;
  private (static?) SomeObject temp2;

  methods...
}

或者有更好的方法吗?感谢您的帮助!

根据答案进行编辑: 不是内存占用是实际问题,而是垃圾收集清理困惑。 SomeObject 是一个类似 Point2D 的类,没有什么内存昂贵的(在我看来)。 我不确定使用(最终是静态的)类级对象作为占位符还是我不知道的一些更高级的方法更好。

最佳答案

在这个过早优化的例子中,我会保持警惕。有缺点,通常,它使代码更复杂(复杂性使错误更有可能),更难阅读,可能引入错误,可能无法提供您预期的加速等。对于一个简单的对象,例如表示 2D 点协调,我不担心重复使用。如果您使用大量内存、避免冗长且昂贵的构造函数,或者将对象构造从频繁执行的紧密循环中拉出来,通常重用会获得最大 yield 。

您可以尝试一些不同的策略:

将责任推给调用者 一种方法是让调用者传入一个预初始化的对象,使方法参数成为最终的。但是,这是否有效取决于您需要对对象执行的操作。

指向临时对象的指针作为方法参数另一种方法是让调用者作为一个对象作为参数传递,其目的本质上是指向一个对象的指针,方法应该在其中执行其临时操作贮存。我认为这种技术在 C++ 中更常用,但工作原理类似,但有时会出现在图形编程等地方。

对象池 重用临时对象的一种常见方法是使用对象池,其中对象是从固定的“可用”对象库中分配的。这有一些开销,但如果对象很大,并且只在短时间内频繁使用,这样内存 fragment 可能是一个问题,那么开销可能足够小,值得考虑。

成员变量 如果您不关心对方法的并发调用(或已使用同步来防止此类调用),您可以模拟“局部静态”变量的 C++ 主义,通过为您的存储创建一个类的成员变量。它降低了代码的可读性,并稍微增加了一些空间来引入对使用变量的代码其他部分的意外干扰,但比对象池的开销更低,并且不需要更改方法签名。如果这样做,您可能还希望对变量使用 transient 关键字,以指示该变量不需要序列化。

除非方法也是静态的,否则我会回避临时的静态变量,因为这可能会在程序运行的整个过程中产生内存开销,这是不希望的,并且与用于此目的的成员变量相同的缺点x2(同一类的多个实例)

关于Java 重用(静态?)对象作为临时对象以提高性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7506218/

相关文章:

java - 并发静态上下文

java - 在枚举中声明常量

java - 如何设置 JFrame 的最小尺寸并使其根据框架厚度进行调整?

java - getInputstream 上的 NullPointerException

android - 为 android 编译 C 库,但未找到符号

java - 网页中的 GPS 位置

c++ - 用于单例销毁的 atexit : failure case

c - 像 "char s[static 10]"这样的函数的数组参数中 static 关键字的用途是什么?

java - 为什么我的程序在尝试运行时会卡住/崩溃?

java - 使用 Apache-poi 将图像插入 excel