10

在我当前的项目(OpenGL Voxel Engine)中,我在生成模型时遇到了一个严重的问题。我有一个非常面向对象的结构,这意味着即使我的顶点的单个参数也是Objects。这样,我Object在大约 5 秒内为 750 个体素创建了大约 75000 秒。Java 在分配 new 时真的这么慢Object吗?还是我错过了代码中某个地方的重大故障?

4

6 回答 6

6

很大的问题。一般来说,它取决于对象类定义和构造对象所需的工作量。

一些问题:

  1. 避免 finalize 方法,
  2. 调整内存和 GC 以避免过多的 GC 活动,
  3. 避免在构造过程中进行大量工作,
  4. 在对象构造期间不要使用同步调用,
  5. 使用弱引用

这些问题解决了我的问题。

另见http://oreilly.com/catalog/javapt/chapter/ch04.html

最后让我向您推荐(已弃用的)对象池模式或重用对象。

总结,不,一般来说java对象创建并不慢

于 2014-01-10T22:12:51.787 回答
5

当然不是。下面的代码分配了 1000 万个对象并将它们存储在一个数组中。在我 5 岁的笔记本上,它在 1.4 秒内完成。

public class Test {
    public static void main(String[] args) {
        Object[] o = new Object[10_000_000];
        long start = System.nanoTime();
        for (int i = 0; i < o.length; i++) {
            o[i] = new Object();
        }
        long end = System.nanoTime();
        System.out.println(Arrays.hashCode(o));
        System.out.println(new BigDecimal(end - start).movePointLeft(9));
    }
}

...即使这个基准测试非常幼稚,因为它不会在启动计时器之前及时触发被测代码的编译。

于 2014-01-10T22:26:39.890 回答
2

简单地创建 75,000 个对象不应该花费 5 秒。看看你的构造函数正在做的工作。除了创建对象之外,您在此期间还做了什么?您是否尝试过对代码进行计时以查明发生延迟的位置?

于 2014-01-10T22:04:33.307 回答
1

对象会比原语慢,而且它们也会消耗更多的内存——所以你可能会过度使用它们。没有看到更多细节很难说。

不过,创建 75000 个对象不会花费很长时间,试试这个:

List<Integer> numbers = new ArrayList<Integer>();
    for(int i = 0;i<75000;i++){
        numbers.add(i); // Note this will autobox creating an Integer object after the first 128
    }
    System.out.println(numbers.size());
}

http://www.tryjava8.com/app/snippets/52d070b1e4b004716da5cb4f

总时间不到一秒。

当我把这个数字增加到 7,500,000 时,它终于花了一秒钟......

于 2014-01-10T22:16:09.020 回答
1

与没有自动内存管理的语言中的常用方法相比,java 中的 new 运算符非常快(例如,new 运算符通常比 C 中的 malloc 命令更快,因为它不需要系统调用)。

尽管新操作员仍然可能成为瓶颈,但在您的情况下肯定不是问题。创建 75K 个对象应该比 5 秒快得多。

于 2014-01-10T22:22:17.767 回答
0

我在创建新对象时遇到了同样的问题。

我在构造函数中的对象分配单个 64x64x64 的三维数组,仅此而已。FPS 下降到四分之一。

我通过重用旧对象并重置它的状态来解决这个问题(顺便说一句,这个方法重新分配这个数组而不会失去性能)。

如果我将分配数组移动到单独的方法中并在创建对象后调用它,速度不会增加到可接受的值。

我创建的这个对象在主游戏循环中。

于 2019-12-29T18:54:22.920 回答