Java ArrayList <primitive data type =“”>仅用于引用的连续内存分配?</primitive>

时间:2013-08-21 04:02:57

标签: java arraylist jvm bytebuffer primitive-types

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

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

对于复杂的数据类型,同样的特征也是可取的。虽然在处理复杂对象的连续内存分配时可能很困难,因为需要计算结构大小并预分配字节缓冲区(structureSize *预期元素数)

我无法想到任何其他有效的方法或解决方案可以连续分配对象(原始/复杂&gt;。任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:2)

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

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

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


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

  • 您必须单独处理原始类型和非原始类型。
  • 最好(从API设计和类型安全角度来看)单独处理各个基本类型。

假设,你可以创建一个类似数组的类型,它实现了任何基本类型的数组,具体取决于运行时参数。只需定义许多方法/重载来获取/设置不同的基元类型。但是,这不是编译时类型安全的,并且API至少可以丑陋 ......

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


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

答案 1 :(得分:1)

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

在OpenJDK / Oracle JVM中,对象按顺序在TLAB中分配。一旦将其复制到幸存者/终身空间中,就会发现逆序。这意味着对象可能在缓存中。

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

答案 2 :(得分:1)

有很多原始馆藏项目,其中一些是:

  1. org.apache.commons.collections.primitives
  2. High Performance Primitive Collections
  3. Trove
  4. 但要注意,使用这些东西,你会越来越难以实现。没有通用的原始集合API。

答案 3 :(得分:0)

由于内存碎片问题,您在尝试做的事情在技术上是不可能的。想一想。如果你的缓冲区需要增长,它需要连续重新分配整个内存,这会迅速破坏内存,即使你在技术上有足够的内存,也会耗尽内存。普通java中最接近的可能是java.nio.IntBuffer。但正如其他人所说,你正试图解决一个不存在的问题。