首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对Java / Android中现有对象的短期引用的开销

对Java / Android中现有对象的短期引用的开销
EN

Stack Overflow用户
提问于 2015-04-02 19:49:58
回答 1查看 498关注 0票数 0

最近,我遇到了一篇关于Android中内存优化的文章,但我认为我的问题更多的是一种通用Java类型。我找不到这方面的任何信息,所以如果你能给我一个好的阅读资源,我将不胜感激。

我说的这篇文章可以找到这里

我的问题涉及以下两个片段:

非最佳版本:

代码语言:javascript
复制
List<Chunk> mTempChunks = new ArrayList<Chunk>();
for (int i = 0; i<10000; i++){
    mTempChunks.add(new Chunk(i));
}

for (int i = 0; i<mTempChunks.size(); i++){
    Chunk c = mTempChunks.get(i);
    Log.d(TAG,"Chunk data: " + c.getValue());
}

优化版本:

代码语言:javascript
复制
Chunk c;
int length = mTempChunks.size();
for (int i = 0; i<length; i++){
    c = mTempChunks.get(i);
    Log.d(TAG,"Chunk data: " + c.getValue());
}

本文还包含以下行(与第一个片段相关):

在上面代码片段的第二个循环中,我们为循环的每一次迭代创建一个新的块对象。因此,它实际上将创建10000个类型为“块”的对象,并占用大量内存。

我正在努力理解的是,为什么提到一个新的对象创建,因为我只能看到堆中已经存在的对象的引用的创建。我知道引用本身要花费4-8字节,这取决于系统,但在这种情况下,它们很快就超出了范围,除此之外,我没有看到任何额外的开销。

也许是创建了一个对现有对象的引用,当大量的对象被认为是昂贵的?

请告诉我这里遗漏了什么,以及这两个片段在内存消耗方面的真正区别是什么。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-02 20:33:22

有两个不同之处:

非最佳的:

  • i < mTempChunks.size()
  • Chunk c = mTempChunks.get(i);

最佳:

  • i < length
  • c = mTempChunks.get(i);

在非最优代码中,为循环的每一次迭代调用size()方法,并创建对Chunk对象的新引用。在最优代码中,避免了重复调用size()的开销,并回收了相同的引用。

然而,这篇文章的作者认为在第二个非最优循环中创建了10000个临时对象,这似乎是错误的。当然,创建了10000个temp对象,但是在第一个循环中,而不是在第二个循环中,没有办法避免这种情况。在第二个非最优循环中,创建了10000个引用.因此,在某种程度上,它并不是最优的,尽管作者把树误认为是森林。

进一步参考资料:

1. 避免创建不必要的对象.

2. 使用增强的循环语法.

编辑:

有人指控我是个骗子。对于那些说呼叫size()没有开销的人,我只能引用官方文档。

3. 避免内部获取器/设置器.

编辑2:

在我的回答中,我最初犯了一个错误,我说引用的内存是在堆栈的编译时分配的。我现在意识到,这个说法是错误的;这实际上是C++中的工作方式,而不是Java。Java的世界是颠倒的:虽然引用的内存确实在堆栈上分配,但在Java中甚至在运行时也是如此。心神不宁!

参考资料:

1. 在java中运行时与编译时内存分配.

2. 在堆栈中还是堆中分配变量引用?.

3. Java虚拟机框架的结构.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29421287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档