目前我使用以下数据结构:
MyObject[] arr = new MyObject[100]
现在数组中的大多数字段实际上是空的(假设 97%)
据我所知,JVM为每个字段保留了一个MyObject
实例所需的内存,因此即使从未真正使用过,也会保留大量内存。
有没有办法节省内存?喜欢只按需为MyObject
分配空间?有没有比简单的数组更好的数据结构?(需要同时高效和快速)
据我所知,JVM为每个字段保留了MyObject的一个实例所需的内存,因此即使从未真正使用过,也会保留大量内存。
不,它没有。它为 100 个对象引用保留足够的内存,而不是 100 个 MyObject
实例。对象引用不大(32 或 64 位,有关详细信息,请参阅此答案)。ASCII-艺术如下。
现在,如果您甚至为保留 100 个大小为 int
或long
的插槽而烦恼,您可以使用 ArrayList
它会根据需要重新分配后备阵列(但这会增加内存碎片),一个根本不使用数组的LinkedList
(但它确实具有的条目具有更高的内存开销), 甚至是像 Map
这样的结构,它(不一定)根本不使用数组(但每个条目的开销更高)。
ASCII 艺术和 100 位数组的详细信息:
因此,当您第一次创建该数组时,内存中的内容如下:
+-----------+|到达 |+-----------+ +------------+|参考 |------>|我的对象[] |+-----------+ +------------+ |空 | |空 | |空 | |(96 更多) | |空 | +------------+
然后你分配一个实例,比如:
arr[1] = new MyObject();
这给你
+-----------+|到达 |+-----------+ +------------+|参考 |------>|我的对象[] |+-----------+ +------------+ |空 | +-------------------+ |参考资料 |---->|我的对象实例 | |空 | +-------------------+ |(96 更多) | |某田 | |空 | |某某其他领域 | +------------+ |... | +-------------------+
。然后也许你添加另一个:
+-----------+|到达 |+-----------+ +------------+|参考 |------>|我的对象[] |+-----------+ +------------+ |空 | +-------------------+ |参考资料 |---->|我的对象实例 | |参考 |--+ +-------------------+ |(96 更多) | | |某田 | |空 | | |某某其他领域 | +------------+ | |... | | +-------------------+ | | +-------------------+ +->|我的对象实例 | +-------------------+ |某田 | |某某其他领域 | |... | +-------------------+
。依此类推,因为您在数组中存储了更多实例。