【问题标题】:How to create memory efficient data structures in Java如何在 Java 中创建内存高效的数据结构
【发布时间】:2017-05-23 05:25:33
【问题描述】:

如果我理解正确,Java 会为每个类创建一些开销。如果我想创建典型的数据结构,例如链表、树、尝试等。单个(列表)项将是类,因此与 C 中的类似数据结构相比,会产生很大的开销。这对于非常大的数据结构来说尤其困难数据集。有没有更好的方法在 Java 中实现这些类型的数据结构,这样我就不会有与在内存中存储类相关的开销?

这里描述了Java 对象的memory consumption。如果我有数百万个对象,使用对象的开销可能会变得太昂贵。所以我想知道是否有更好的方法来处理这种情况。

【问题讨论】:

  • 在java集合中,item是相同类型的对象
  • java 有一组非常完善的类和接口...请参阅 java.util.collection,如您所知,在像 C 这样的低级别上不会发生任何事情,因为虚拟机总是在中间
  • 定义重大开销
  • 您是在问Java 中是否有一个集合是按标准用C/C++/other-low-level-lang 实现的(所有VM 实现都有)?或者如果有特定的实现可以使用?
  • “单个(列表)项将是类,因此与 C 中的类似数据结构相比,会产生很大的开销” ...类加载和对象实例化机制在这一点上,Java 中的 in Java 已经持续开发了数十年,您可以指望它们快速高效。例如,这些设施和垃圾收集器将胜过大多数自滚动对象池(数据库连接等非常昂贵的对象除外)。您选择 Java 正是因为您想要对象抽象的好处,否则您将在 C 级别进行开发。

标签: java memory data-structures


【解决方案1】:

您可以在字节块上实现这些集合(以new byte[...]ByteBuffer.allocate[Direct](...)unsafe.allocateMemory(...) 形式获得)。然后,您可以手动管理此内存:将您的对象与其他数据一起打包/解包到字节块中(例如二叉树的leftright 值的索引,链表的next 的索引等。 ) 这样您就不必在对象标头、额外引用、对齐方式上花费内存(尽管您可能决定确实需要引入自己的对齐方式);可以将您的对象放在堆外;可以将它们映射到文件系统以实现持久性等。但是,这并不简单并且会引起微妙之处(例如,您可能会开始依赖malloc 实现并失去 JVM 堆优化;失去内存模型保证;您的对象可能在缓存行之间拆分;您将失去 GC 压缩等的好处)。我并不是说这些中的任何一个都是阻碍,只是它并不全是玫瑰,你应该明白你到底得到了什么。如果您有数百万个对象,那么开销很可能是 100 兆字节。确保尝试保存它们是值得的(与需要多少必要数据相比 + 与您的堆有多大相比)。

【讨论】:

    【解决方案2】:

    您始终可以使用 Java 中的 c++ 本机代码 (JNI) 来提高性能和控制级别(我认为您并不真的需要这个,我不确定您是否可以超越标准的 Java 代码)。

    【讨论】:

      【解决方案3】:

      在“c++ library jni”上的快速 Google 搜索出现了这篇题为 Wrapping a C++ library with JNI – introduction 的文章,这可能会很有趣。我没看过,所以对内容不做推荐或保证。

      【讨论】:

        【解决方案4】:

        如果您有数据集,其中 java 的对象大小开销是一个实际问题,我建议考虑使用数据库。您可以从内存中的嵌入式数据库开始,例如 sqlite、h2 或 redis。

        随着数据变得越来越大,您将需要更复杂的管理。手动更新交叉引用、索引等以确保可以有效地查询您的数据是数据库可以提供帮助的一项巨大工作。

        使用适当的数据库还可以让您在数据开始达到数百 GB 级别而不再适合内存时,以及当您必须过渡到实际开始使用磁盘时,甚至当您当您必须使用多台机器来保存数据时达到数 TB 级别,而无需进行重大重写。

        一个合适的数据库可以随着你的应用程序一起增长,内存中的一堆对象不能。

        【讨论】:

        • OP 声称“对数据库存储不实用的数据结构”——几乎可以肯定这不是真的,但可能应该在这个答案中得到解决。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-05-20
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        • 2015-06-26
        • 2020-08-22
        • 1970-01-01
        相关资源
        最近更新 更多