做“非零”数组原语需要更多内存?
大家好,在编写数组列表实现时,我知道在删除时将 Item(x)
设置为 null(而不是简单地 quantity -= 1
)非常重要,因此以防止内存泄漏。
但是,如果我的数组列表是原始 int 数组列表(由 int[]
支持),将其设置为 0 是否有意义?
类似地,对于原始字符的数组列表(由char[]
支持),当调用RemoveRange()时,用\u0000
填充该范围是否有意义?或者简单地更新长度
和指针而不修改后备数组就完全没问题吗?
用零填充的整数数组是否比用整数值填充的等长数组可能占用更少的内存,因为运行时可以进行优化?
Hi all when writing an array list implementation, I understand it is important to set Item(x)
to null when it is removed (instead of simply quantity -= 1
) so as to prevent memory leaks.
However, if my array list is a primitive int array list (backed by a int[]
), does it make sense to set it to 0?
Similary, for an array list of primitive chars (backed by a char[]
), when RemoveRange() is called, does it make sense to fill that range with \u0000
? Or is it totally fine simply to update the length
and pointers without modifying the backing array?
Is an array of ints filled with zeros possibly less memory-occupying than an equal length array filled with integer values because the runtime could make optimizations ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
假设在这两种情况下我们都处理一个
int[]
- 否。相同类型和相同长度的两个数组将始终占用相同的内存量。没有需要用 0 覆盖“现在为空”的数组元素。它不会造成任何损害(除了微小的性能优势),甚至可能在调试时使事情变得更简单,但你不这样做不需要。
Assuming in both cases we're dealing with an
int[]
- no. Two arrays of the same type and the same length will always occupy the same amount of memory.There's no need to overwrite your "now empty" array elements with 0. It wouldn't do any harm (beyond a tiny performance benefit), and may even make things simpler when debugging, but you don't need to.
这不是真的。将变量设置为 null 并不总是必要的,不这样做并不意味着存在内存泄漏。
不,对于基元来说,这根本不重要,0 或
\u0000
(对于字符)只是一个与任何其他值一样的值。它并不占用更少的空间。This isn't true. Setting variables to
null
is not something that is always necessary and not doing so does not mean that you have a memory leak.No, for primitives it doesn't matter at all, 0 or
\u0000
(for a char) is just a value like any other value. It doesn't take up less space.不,对于原始类型没有必要这样做(即将它们设置为 0),因为“槽”被显式清空的唯一原因是为了防止对它们的虚假引用,从而搞乱垃圾收集。
No, it's not necessary to do so with primitive types (i.e. set them to 0) since the only reason "slots" are explicitly nulled out are to prevent fake references to them thereby screwing around with garbage collection.
您不能拥有 ArrayList或任何其他带有基元的容器类。关于普通数组,请参阅 Jon Skeets 的回答。
You can't have an
ArrayList<int>
nor any other container class with primitives. Regarding plain arrays, see Jon Skeets answer.不,您需要使数组中的对象槽无效以防止泄漏。如果该对象仍然被你的数组引用,那么它就不能被GC - 所以你引用的泄漏。
另一方面,基元无论如何都是在堆栈上分配的,而不是在堆上,因此无论如何也不会进行 GC。作为类的实例变量的基元被存储为相关对象的字段,并在对象被 GC 时被清除。
此外,JLS 表明原语的大小是特定于 VM 的,但大多数(全部?)VM 当前支持 4 字节整数。有关详细信息,请参阅 JLS:
No, you need to nullify the object slot in the array to prevent the leak. If the object is still referenced by your array then it can't be GC'd - so the leak you refer to.
Primitives on the other hand are allocated on the stack anyway, not the heap, so aren't GC'd anyway. Primitives that are instance vars of classes are stored as fields of the relevant object and cleaned up when the object is GC'd.
Additionally, the JLS indicates that the size of a primitive is VM-specific but most (all?) VMs currently support 4byte ints. See the JLS for more info:
基元和引用始终占据相同的空间量。
Primitives and references always occupy the same amount of space.