【发布时间】:2013-01-14 17:39:56
【问题描述】:
我使用UUID.toString() 将大量Java UUID 存储到HashMap 作为行。由于数据很大,很快就会抛出OutOfMemoryError。现在我正在考虑一种紧凑的方式来表示UUID,最好是类似long,然后我可以很容易地用long 表示重构UUID。这可能吗?
【问题讨论】:
标签: java out-of-memory uuid
我使用UUID.toString() 将大量Java UUID 存储到HashMap 作为行。由于数据很大,很快就会抛出OutOfMemoryError。现在我正在考虑一种紧凑的方式来表示UUID,最好是类似long,然后我可以很容易地用long 表示重构UUID。这可能吗?
【问题讨论】:
标签: java out-of-memory uuid
UUID 本质上是一个数字,但它是一个 128 位的数字,是 java 长度的两倍。您可以使用 BigInteger(这可能并不比将 UUID 存储为字符串更节省空间),或者您可以将 UUID 封装在一个包含两个 long 的对象中——一个用于前 64 位,一个用于后 64 位。
给定 UUID 550e8400-e29b-41d4-a716-446655440000,您需要创建两个 long,一个包含数字 0x550e8400e29b41d4,另一个包含数字 0xa716446655440000。
【讨论】:
我使用
UUID.toString()将大量JavaUUID存储到HashMap作为行。
所以你的意思是HashMap<String, MyObject>?
与HashMap<String, MyObject> 相比,通过HashMap<UUID, MyObject> 存储UUID 本身将节省空间。 UUID 比 String 占用的空间更少(两个 long 值变为 16 字节,而 char[36] 为 72 字节,这将为您节省近 80% 的空间)。
如果更改还不够,那么请考虑 UUID 值在 JVM 中是否重要。如果 ID 只需要对于单个进程是唯一的(您是将HashMap 保存到磁盘还是在 Java 进程之间共享它?),那么您可以只使用int,因为@987654335 @ 无论如何不能大于Integer.MAX_VALUE。因此,您将拥有HashMap<Integer, MyObject>,而不是HashMap<UUID, MyObject>。更好的是,如果您要拥有少于 216 个对象,则可以使用 Short,从而节省更多空间。但是,如果您收到 OutOfMemoryError,我怀疑您可能拥有超过 65536 个对象。
最后,如果所有其他方法都失败了,请为您的 JVM 分配更多内存,如 this question 中所示。
【讨论】: