如果java堆中存在对象X,并且我知道java堆上对象X的地址,那么本机代码是否可以直接从内存中访问这个对象而不涉及JNI?反之亦然,如果java代码知道本地堆上对象Y的地址,那么java可以在不涉及JNI的情况下访问它吗?
更准确地说,“java对象是以与本机对象相同的方式存储在内存中,还是有任何不同?”如果不是,java和本机中的byteArray对象会以同样的方式存储吗?
请提供您的建议和参考。
编辑:也许这是一个正确的问题,为什么对象需要通过JNI从java堆传输到本机堆?为什么本机堆不能直接访问java堆对象?
发布于 2017-04-11 03:18:56
Java代码可以访问本机对象吗?不是的。Java代码由JVM管理。(更准确地说,这是字节码,而不是Java代码。)JVM规范不允许字节码访问任意内存。字节码甚至不能访问JVM堆上的任意地址。例如,私有字段只能由同一类中的字节码访问。
本机代码可以直接访问JVM堆对象(没有JNI)吗?是。本机代码在与JVM相同的进程和地址空间中运行。据我所知,在大多数操作系统和硬件平台上,这意味着本机代码可以在地址空间中做它想做的任何事情。
本机代码应该直接访问JVM堆对象吗?绝对不是那么回事。
首先,JVM规范没有指定JVM堆上对象的布局,甚至没有指定字节数组的布局。例如,JVM可以将数组分割成块,并在字节码使用数组时透明地转换地址。如果您试图编写访问数组的本机代码,则必须重新实现该转换。这样的代码可能在一个JVM实现中工作,但可能在另一个JVM中不起作用,甚至在同一个JVM的较新版本中也不起作用,或者在同一个JVM中运行时使用不同的配置。这就是为什么您必须使用JNI的原因之一:它为本机代码提供了JVM堆上的对象的定义良好的“视图”。
其次,JVM垃圾收集器可以随时在堆上的对象周围移动。本机代码应该通过句柄访问JVM堆对象。垃圾收集器知道它并在必要时更新句柄。试图绕过句柄的本机代码永远无法确定对象是否仍然存在。
第三个问题是本机代码,它直接修改JVM堆中对象之间的指针。根据垃圾收集器算法的不同,这可能会导致各种问题。
简而言之:您可能可以直接从本机代码中访问JVM堆对象,但是您几乎肯定不应该访问。
发布于 2017-02-23 22:37:58
简短回答:不。
除了Java/C++问题之外,这与基本的OS概念相矛盾。由于每个进程都有自己的地址空间,因此一个进程无法到达其他进程的任何对象。
只有当进程(试图到达他人的内存)在内核空间中运行,并且底层操作系统允许操作,或者涉及诸如“共享内存”之类的实用程序时,这个限制才能得到缓解。即使是这样,您也将面临虚拟地址空间问题。内存的相同物理部分在不同的进程中以不同的值进行处理。这就是为什么,如果您认为您知道一个对象的地址,这个地址在其他进程中是虚拟的和无用的。
编辑:如果它们不在不同的进程中,那么答案肯定是肯定的。理论上,您可以实现自己的JNI :)。
发布于 2017-02-24 07:03:10
https://stackoverflow.com/questions/42426994
复制相似问题