4

我想分配一个原始数据类型对象的数组列表,如 int、char 等(不是数组,因为它将来会增长可能不是线性的),但需要存储在 RAM 中的连续内存位置(jvm 托管堆)。但是自从我为 ex 的原始数据类型声明 ArrayList 时。ArrayList 为 int,内部 jvm 映射到 ArrayList<Integer> 类型的对象。
现在的问题是 ArrayList 持有对存储在 jvm 托管内存空间中不同位置的对象的连续引用。但我最初的想法是连续存储实际数据对象而不仅仅是参考!但我不知道如何实现它?

我能想到的一种解决方案是分配大尺寸字节数组,从而创建一个连续的内存缓冲存储!如果在 2000 个预分配字节中存储了 1000 个 int 对象,开发人员需要管理如何在 101 个索引位置获取一些存储在这个手动创建的缓冲区(假设我们建模为 2 个字节/int)中的 int 数据!



复杂数据类型也需要相同的功能。虽然处理复杂对象的连续内存分配可能很困难,因为需要计算结构大小并预分配 (structureSize * No. of Elements Expected) 的字节缓冲区



对于连续分配对象(原始/复杂>),我想不出任何其他有效的方法或解决方案。任何人都可以帮助我吗?

4

4 回答 4

2

没有单一的解决方案可以满足您的要求。

如果您想要一个原始类型的类数组结构,那么您需要使用该原始类型的数组或包装该原始类型1的数组的某个类。如果您尝试实现自定义类,它不能是泛型的(在原始类型上),因为原始类型不能用作泛型类型参数。因此,它不能是ArrayList派生自 的一个或任何其他类型Collection

如果你想要一个引用类型的类数组结构,那么你可以使用一个数组,或者一个ArrayList.


简而言之,如果您不愿意使用包装器类型(Integer等):

  • 您必须分别对待原始类型和非原始类型。
  • 最好(从 API 设计和类型安全的角度)分别处理各个原始类型。

假设您可以创建一个类数组类型,该类型实现任何原始类型的数组,具体取决于运行时参数。只需定义许多方法/重载来获取/设置不同的原始类型。但是,这不是编译时类型安全的,而且 API 会很丑……至少可以这么说。

您使用 a 的想法与ByteBuffer上述基本相同……或者更糟的是,如果您预计应用程序代码会在字节和名义上的“数组”基本类型之间执行所有索引和编码/解码。(而且你最好从 abyte[]而不是 a开始ByteBuffer。)


1 - 例如,Trove 集合类之一。

于 2013-08-21T04:27:09.340 回答
1

有很多原始的收藏项目,这里有一些:

  1. org.apache.commons.collections.primitives
  2. 高性能原始集合
  3. 特罗夫

但是请注意,使用这些东西,您会越来越难以实施。没有通用的原始集合 API。

于 2013-08-21T07:53:22.650 回答
1

免责声明:无论如何都没有指定,所以它可能是偶然的。

在 OpenJDK/Oracle JVM 中,对象在 TLAB 中按顺序分配。一旦它被复制到幸存者/终身空间中,就会以相反的顺序被发现。这意味着对象很可能一起在缓存中。

一个简单的解决方案是使用像 Trove 这样的基元集合,其中基元实际上位于原始数组中。

于 2013-08-21T05:58:18.650 回答
0

由于内存碎片问题,您正在尝试做的事情在技术上是不可能的。想想看。如果你的缓冲区需要增长,它需要重新分配整个内存量,这会连续地快速分割内存,即使你在技术上会有足够的内存,也会让你的内存不足。在常规 java 中最接近的可能是 java.nio.IntBuffer。但是就像其他人所说的那样,您正在尝试解决一个不存在的问题。

于 2013-08-21T08:20:29.893 回答