目前我使用以下数据结构:
MyObject[] arr = new MyObject[100]
现在数组中的大多数字段实际上都是空的(让我们说97%)
据我所知,JVM为每个字段保留了一个MyObject
实例所需的内存,因此即使从未真正使用过,也会保留大量内存。
有没有办法节省内存?比如只按需要为MyObject
分配空间?
有一个更好的数据结构,然后只是一个简单的数组? (需要高效且快速的记忆)
答案 0 :(得分:5)
据我所知,JVM为每个字段保留了一个MyObject实例所需的内存,因此即使它从未真正使用过,也会保留大量内存。
不,它没有。它为100个对象引用保留了足够的内存,而不是MyObject
的100个实例。对象引用不大(32位或64位,有关详细信息,请参阅this answer)。下面是ASCII艺术。
现在,如果您仍然需要保留100个int
或long
大小的插槽,那么您可以使用ArrayList
根据需要重新分配支持数组(但这可能会增加内存碎片),LinkedList
根本不使用数组(但是 所拥有的条目具有更高的内存开销),甚至是结构例如Map
根本没有(必然)使用数组(但每个条目的开销也更高)。
ASCII-art和100位数组的详细信息:
所以当你第一次创建那个数组时,这就是你在内存中所拥有的:
+-----------+ | arr | +-----------+ +------------+ | reference |------>| MyObject[] | +-----------+ +------------+ | null | | null | | null | | (96 more) | | null | +------------+
然后你分配一个实例,比如说:
arr[1] = new MyObject();
那会给你
+-----------+ | arr | +-----------+ +------------+ | reference |------>| MyObject[] | +-----------+ +------------+ | null | +-------------------+ | reference |---->| MyObject instance | | null | +-------------------+ | (96 more) | | someField | | null | | someOtherField | +------------+ | ... | +-------------------+
...那么也许你又添加了另一个:
+-----------+ | arr | +-----------+ +------------+ | reference |------>| MyObject[] | +-----------+ +------------+ | null | +-------------------+ | reference |---->| MyObject instance | | reference |--+ +-------------------+ | (96 more) | | | someField | | null | | | someOtherField | +------------+ | | ... | | +-------------------+ | | +-------------------+ +->| MyObject instance | +-------------------+ | someField | | someOtherField | | ... | +-------------------+
...等等,在数组中存储更多实例。