【问题标题】:How Java int[ ] array is implemented inside JVM?Java int[ ] 数组是如何在 JVM 内部实现的?
【发布时间】:2014-04-10 11:12:06
【问题描述】:

我试图了解 JVM 如何在内部实现原始类型数组,例如 int []

我的问题分为两部分:

1 - 它在内部使用 ByteBuffer 吗?我在哪里可以找到源代码,然后可能根据我的需要进行更改(以制作我自己的修改后的 JVM)。

2 - 有没有办法欺骗javac 不使用int [] 的内置实现,而是使用类路径-cp 中的库提供的实现?这可能吗?如何实现?

我的动机是在 JVM 外部的内存中声明此 int [](使用 allocateDirect())并从本机 JNI 代码外部访问它。这应该避免内存复制开销。

-B

【问题讨论】:

    标签: java arrays performance jvm java-native-interface


    【解决方案1】:
    1. int[] 是原始类型。 ByteBuffer 可能基于 int[] 但相反的情况肯定不正确。它几乎肯定是一个字对齐的连续内存块,在该块的每个字中存储 32 位值。有几个JVM是开源的,如果你真的想看代码,你可以去看看,但它会是高级的东西。

    2. 没有简单的方法可以做到这一点。

    听起来您正在尝试以非常复杂的方式做某事。最好描述您正在尝试解决的实际问题,而不是通过尝试解决该问题来询问问题。

    【讨论】:

    • 我正在使用 MPJ Express(Java 中的 MPI 实现),它使用内部缓冲层来缓冲用户数据。问题在于这种缓冲。在高端互连(Infiniband)上,将数据复制到内部缓冲层会显着降低性能,即与原生 C MPI 实现(如 MVAPICH 或 Open MPI)相比带宽相对较低。所以我想绕过这个缓冲层,直接访问用户数据而不改变API(用户程序)。
    • @Bibrak 你用System.arraycopy 复制数据吗?
    • @AlexeiKaigorodov 但它不会复制吗?我想做一个零拷贝
    • @Bibrak System.arraycopyfor(){} 循环快得多。先试试看,如果还是瓶颈,再找其他办法。
    • @AlexeiKaigorodov 实际上 MPJ Express 在传输之前使用ByteBuffer 作为内部存储,asIntBuffer 是从ByteBuffer 检索IntBuffer 并将数据从用户int [] 打包到其中src,使用IntBufferput(int[] src, int offset, int length)的标准API函数。优化就在那里。但我只是想去掉这个内部缓冲,直接在 JNI 中访问用户 int []
    【解决方案2】:

    您可以使用 sun.misc.Unsafe 来分配和访问原始共享内存,而不是使用 Java IntBuffer 或 JNI。这很危险,但它绝对是从 Java 和其他进程访问共享内存的最快方式。

    不安全方法的有用指南是here

    【讨论】:

    • sun.misc.Unsafe 确实提供了分配本机内存的选项,但问题仍然存在,因为用户数组(普通、普通、原始数组)并未在本机隐式分配。
    • 对。它是 Java 数组的替代方案,可以更轻松地与其他进程进行互操作。虽然如果你可以做一些非常不安全的诡计来让 JVM 相信它可以作为具有标准语法的 int[] 数组访问,我不会感到惊讶 - int[] 的内存中标头非常简单。嗯……
    • 你的意思是有一个自定义的 JVM 吗?
    • 不需要自定义JVM;可以使用 Unsafe 进行任意内存突变。其中一些突变使您可以创建具有与 Java 数组相同的布局、堆外的结构。唯一的问题是您是否可以采用该结构并将其转换为“适当的”int []。我有点相信这是可能的,但我还没有尝试过。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-20
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 2011-08-06
    • 2011-01-17
    • 2011-04-26
    相关资源
    最近更新 更多