- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
清空一个集合(在我的例子中是一个 ArrayList)与创建一个新集合(并让垃圾收集器清除旧集合)的优缺点是什么。
具体来说,我有一个 ArrayList<Rectangle>
调用list
.当某种情况发生时,我需要清空list
并用其他内容重新填充它。我应该调用list.clear()
或者只是制作一个新的ArrayList<Rectangle>
让旧的垃圾收集?每种方法的优缺点是什么?
最佳答案
回收 ArrayList
(例如通过调用 clear
)的优点是可以避免分配新的开销以及增加它的成本...如果您没有提供良好的 initialCapacity
提示。
回收ArrayList
的缺点包括:
clear()
方法必须将 null
分配给 ArrayList
的后备数组中的每个(已使用)槽。
clear()
不会调整后备数组的大小以释放内存。因此,如果您反复填充和清除列表,它将最终(永久)使用足够的内存来表示它遇到的最大列表。换句话说,您增加了内存占用。你可以通过调用 trimToSize()
来解决这个问题,但这会创建一个垃圾对象,等等1。
存在可能影响性能的地方性和跨代问题。当您反复回收 ArrayList
时,对象及其支持数组可能会被永久使用。这意味着:
列表对象和表示列表元素的对象可能位于堆的不同区域,可能会增加 TLB 未命中和页面流量,尤其是在 GC 时。
将(年轻一代)引用分配到(永久)列表的后备数组中可能会产生写屏障开销...取决于 GC 实现。
不可能准确地为实际应用程序的性能权衡建模。变量太多了。然而,“公认的智慧”是,如果你有足够的内存2 和一个半体面的垃圾收集器,回收通常不是一个好主意。
同样值得注意的是,现代 JVM 可以非常有效地分配对象。它只需要更新堆的“空闲”指针并写入 2 或 3 个对象头字。内存归零是由 GC 完成的......除了这样做的工作大致等同于 clear()
所做的工作以清空正在回收的列表。
1 - 创建一个新的 ArrayList 比调用 clear() 后跟 trimToSize(...) 更好。使用后者,您将获得垃圾收集开销和多余空值的开销。
2 - 如果垃圾对象与非垃圾对象的比例很高,则复制收集器的效率更高。如果分析这种收集器的工作方式,成本几乎都发生在查找和复制可达对象上。对垃圾对象唯一需要做的就是将撤离的“来自”空间的 block 零写入准备好分配新对象。
我的建议是不要回收 ArrayList
对象,除非您有明显的需要最小化(垃圾)对象创建率;例如因为它是减少(有害的)GC 暂停的唯一选择。
在所有条件相同的情况下,在现代 Hotspot JVM 上,我的理解是通过执行以下操作可以获得最佳性能:
initialSize
提示。稍微高估总比低估好。关于java - 清空一个 ArrayList 还是只创建一个新的并让旧的被垃圾收集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18370780/
我是 C 新手,还没有真正掌握 C 何时决定释放对象以及何时决定保留对象。 heap_t 是指向结构堆的指针。 heap_t create_heap(){ heap_t h_t = (heap
我有一个问题,我不知道如何解决。问题是: char * ary = new Char[]; ifstream fle; fle.open(1.txt, ios_base::binary); fle.s
假设我在 C# 中有字符串:“我看不到你……” 我想删除(替换为空等)这些“’”符号。 我该怎么做? 最佳答案 那个“垃圾”看起来很像有人将 UTF-8 数据解释为 ISO 8859-1 或 Wi
我无法在解析方法中更改蜘蛛设置。但这绝对是一种方式。 例如: class SomeSpider(BaseSpider): name = 'mySpider' allowed_domains
在开始之前,我们先回顾一下堆是个什么玩意,大家可能都知道,我们每天创建的Java对象几乎都存放在堆上面,所以说堆是一个巨大的对象池一点都不过分,在这个对象池里面管理者数据巨大的对象实例。 在对
我想知道为什么 printf() 在提供数组且没有格式化选项时成功打印字符数组,但在使用整数数组时编译器会抛出警告并打印垃圾值。 这是我的代码: #include int main() { c
我正在研究 Scrapy 库并尝试制作一个小爬虫。 这是爬虫的规则: rules = ( Rule(LinkExtractor(restrict_xpaths='//div[@class="w
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Printing a string to a temporary stream object in C++
这个问题在这里已经有了答案: Are WebGL objects garbage collected? (2 个答案) 关闭 3 年前。 在 WebGL 中,纹理的创建和销毁使用: WebGLTex
我继承了以下代码: (为保护无辜者更改了一些名称。) package foo.bar.baz; import javax.swing.JPanel; //Main panel in the GUI c
如果我没记错的话,在某些情况下,Java 中的 lambda 会生成为匿名类实例。例如,在这段代码中,lambda 需要从外部捕获一个变量: final int local = 123456; lis
我正在阅读托管代码中的内存泄漏,想知道是否可以在 C# 不安全代码中创建它? unsafe { while(true) new int; } 我不确定如果它作为不安全代码运行,是否会被 GC
假设我有以下用 HTML 编写的网页(仅正文部分): ... function fn() { // do stu
我想知道是否有简单的命令可以删除在 latex 编译过程中生成的所有不必要的文件,例如.aux、.log 等 最好将它链接到常规的 Latex 构建命令,这样在我点击“编译”后,垃圾文件就会被删除。
Java 在 Java7 中引入了带有字符串的 switch case。我想知道使用这样的开关盒是否会产生垃圾。 例如在我的程序中, String s = getString(); switch(s)
Cevelop将 char junk 作为“未初始化的变量”对象。在这种情况下,解决问题的正确方法是什么? friend std::ostream& operator>(std::istream&
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
我正在编写一个发送和接收纯文本的小型 boost asio tcp 服务器和客户端。通信或多或少是请求响应。在测试期间,我想我只是向服务器发送垃圾数据,向它发送 100.000 个请求。 客户端发
我正在使用 SAX 来读取/解析 XML 文档,并且它工作正常,除了这个特定的站点,在该站点中 eclipse 告诉我“文档元素之后的垃圾”并且我没有返回任何数据 http://www.zachblu
这是我的 Scrapy 爬虫代码。我正在尝试从网站中提取元数据值。没有元数据在一个页面上出现多次。 class MySpider(BaseSpider): name = "courses"
我是一名优秀的程序员,十分优秀!