java对象能否从本机代码访问,反之亦然?

java对象能否从本机代码访问,反之亦然?,java,c++,operating-system,java-native-interface,Java,C++,Operating System,Java Native Interface,如果java堆中存在一个对象X,并且如果我知道java堆上对象X的地址,本机代码是否可以直接从内存访问该对象而不涉及JNI?反之亦然,如果java代码确实知道本机堆上对象Y的地址,java可以在不涉及JNI的情况下访问它吗 更准确地说,“java对象在内存中的存储方式是否与本机对象相同,或者有什么不同?”。如果不是,java和native中的byteArray对象会以相同的方式存储吗 请提供您的建议和参考 编辑:也许这是一个正确的问题,为什么需要通过JNI将对象从java堆传输到本机堆?为什么j

如果java堆中存在一个对象X,并且如果我知道java堆上对象X的地址,本机代码是否可以直接从内存访问该对象而不涉及JNI?反之亦然,如果java代码确实知道本机堆上对象Y的地址,java可以在不涉及JNI的情况下访问它吗

更准确地说,“java对象在内存中的存储方式是否与本机对象相同,或者有什么不同?”。如果不是,java和native中的byteArray对象会以相同的方式存储吗

请提供您的建议和参考

编辑:也许这是一个正确的问题,为什么需要通过JNI将对象从java堆传输到本机堆?为什么java堆对象不能被本机堆直接访问?

简短回答:否

除了Java/C++问题之外,这与基本操作系统概念相矛盾。由于每个进程都有自己的地址空间,因此一个进程无法到达其他进程的任何对象

只有当进程(试图访问他人内存的进程)在内核空间中运行,并且底层操作系统允许操作,或者涉及诸如“共享内存”之类的实用程序时,才能减轻此限制。即使是这样,你也会面临问题。内存的相同物理部分在不同的进程中使用不同的值进行寻址。这就是为什么,如果你认为你知道一个对象的地址,这个地址是虚拟的,在其他进程中是无用的


编辑:如果他们不在不同的流程中,那么答案肯定是肯定的。理论上,您可以实现自己的JNI:)。

一个可能的答案是使用APR(Apache便携式运行时)是的,我知道它基于JNI,但它有共享内存的概念。因此,可以绑定由另一个程序创建的共享内存空间(反之亦然)


除了JNI部分,这似乎是不可能的。

Java代码可以访问本机对象吗?否。Java代码由JVM管理。(更准确地说,它是字节码,而不是Java代码。)JVM的规范不允许字节码访问任意内存。字节码甚至不能访问JVM堆上的任意地址。例如,私有字段只能由同一类中的字节码访问

本机代码是否可以直接访问JVM堆对象(没有JNI)?对本机代码与JVM在相同的进程和地址空间中运行。据我所知,在大多数操作系统和硬件平台上,这意味着本机代码可以在该地址空间中执行它想要的任何操作

本机代码是否应该直接访问JVM堆对象?绝对不是

首先,JVM规范没有指定JVM堆上对象的布局,甚至没有指定字节数组的布局。例如,当字节码使用数组时,JVM可以将数组分割成块并透明地转换地址。如果试图编写访问数组的本机代码,则必须重新实现该转换。这些代码可能在一个JVM实现中工作,但可能在另一个JVM实现中不工作,或者甚至可能在同一JVM的较新版本中也不工作,或者在同一JVM中以不同的配置运行时也不工作。这就是必须使用JNI的原因之一:它为本机代码提供了JVM堆上对象的定义良好的“视图”

其次,JVM垃圾收集器可以随时在堆上移动对象。本机代码应该通过句柄访问JVM堆对象。垃圾收集器知道这一点,并在必要时更新句柄。试图绕过句柄的本机代码永远无法确定对象是否仍然存在

第三个问题是直接修改JVM堆上对象之间指针的本机代码。根据垃圾收集器算法的不同,这可能会导致各种问题


简而言之,你可能直接从本地代码访问JVM堆对象,但你几乎不应该访问它。

不,尝试读取java没有C++的指针,为什么要这样编程?什么是大任务?为什么要这样做并绕过JNI?这看起来像是一个@AndrewHenle编辑的问题。这个问题不是指两个不同的过程。这只是一个java进程。APR与JNI无关。@JonaChristopherSahnwaldt您认为JVM如何访问.dll或.APR?请解释JVM和APR之间的关系。对不起,但是你似乎不知道你在说什么。看看APR库的这一部分:请不要忘记对象只是“内存结构”。。。因此,是的,java可以访问本机对象,为此,您必须将JNI包装器写入so或可以访问共享内存的DLL,然后您必须解码内存以满足您的需要。您链接的代码与java、JVM或JNI无关。非常感谢Jona。