使用sun.misc.Unsafe获取Java数组项的地址?

发布于 2024-12-12 05:52:16 字数 136 浏览 0 评论 0原文

我正在努力理解 sun.misc.Unsafe 的文档——我想因为它不适合一般用途,所以没有人真正费心让它可读——但我实际上真的需要一种方法来查找中元素的地址一个数组(以便我可以将指向它的指针传递给本机代码)。有没有人有任何可以执行此操作的工作代码?可靠吗?

I'm struggling to understand the documentation of sun.misc.Unsafe -- I guess as it's not intended for general use, nobody's really bothered with making it readable -- but I actually really need a way to find the address of an element in an array (so that I can pass a pointer to it to native code). Has anyone got any working code that does this? Is it reliable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感性 2024-12-19 05:52:16

这是一个工作示例。但请小心,因为不恰当地使用 Unsafe 类可能很容易使 JVM 崩溃。

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class UnsafeTest {

    public static void main(String... args) {
        Unsafe unsafe = null;

        try {
            Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (sun.misc.Unsafe) field.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }

        int ten = 10;
        byte size = 1;
        long mem = unsafe.allocateMemory(size);
        unsafe.putAddress(mem, ten);
        long readValue = unsafe.getAddress(mem);
        System.out.println("Val: " + readValue);

    }
}

Here is a working sample. Please be careful however as you may easily crash your JVM with unappropriate usage of Unsafe class.

import java.lang.reflect.Field;

import sun.misc.Unsafe;

public class UnsafeTest {

    public static void main(String... args) {
        Unsafe unsafe = null;

        try {
            Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (sun.misc.Unsafe) field.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }

        int ten = 10;
        byte size = 1;
        long mem = unsafe.allocateMemory(size);
        unsafe.putAddress(mem, ten);
        long readValue = unsafe.getAddress(mem);
        System.out.println("Val: " + readValue);

    }
}
败给现实 2024-12-19 05:52:16

您可以使用 ByteBuffer.allocateDirect() 直接缓冲区,而不是使用数组。它的地址位于一个字段中,并且该地址在 ByteBuffer 的生命周期内不会改变。直接 ByteBuffer 使用最小的堆空间。您可以使用反射来获取地址。


你可以使用Unsafe来获取地址,问题是GC可以随时移动它。对象并不固定在内存中。

在 JNI 中,您可以使用特殊方法将数据复制到 Java 对象或从 Java 对象复制数据,以避免此问题(以及其他问题)。如果您想使用 C 代码在对象之间交换数据,我建议您使用这些方法。

Instead of using an array you can use a ByteBuffer.allocateDirect() direct buffer. This has the address in a field and this address doesn't change for the life of the ByteBuffer. A direct ByteBuffer uses minimal heap space. You can get the address using reflection.


You can use Unsafe to get an address, the problem is that the GC can move it at any time. Objects are not fixed in memory.

In JNI you can use special methods to copy data to/from Java objects to avoid this issue (and others) I suggest you use these if you want to exchange data between Objects with C code.

捂风挽笑 2024-12-19 05:52:16

为什么? JNI 中有很多工具可用于处理 Java 数组的内容。您不需要使用下周可能不存在的未记录的内部 Sun 类。

Why? There are plenty of facilities in JNI for dealing with the contents of Java arrays. You don't need to use undocumented internal Sun classes that mightn't be there next week.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文