通过java使用本机内存
Posted
技术标签:
【中文标题】通过java使用本机内存【英文标题】:Using the native memory through java 【发布时间】:2012-09-04 18:17:47 【问题描述】:有时,需要绕过应用程序的堆内存限制并使用超出允许范围的内存。
我想到了一个解决方案,其中包括一种缓存机制,它将字节存储在本机内存中(不是在堆内存中,而是在非托管内存中)。
当然,我会考虑系统的最大可用大小。
所以,对direct buffers有所了解,我用它在本机内存中存储了一个字节数组:
final ByteBuffer nativeBytes=ByteBuffer.allocateDirect(bytes.length);
nativeBytes.put(bytes);
但是,在 android 上,用于此的内存似乎是在堆中使用的,而不是在本机内存中。
发生了什么事?从本机内存存储和加载数据是否有简单的替代方法?
【问题讨论】:
没有“原生内存”这样的东西;内存不了解本机与字节码。这让你的问题很不清楚。 有托管内存和非托管内存。托管内存的限制约为 48MB,当你通过它时,你会得到 OOM 异常。非托管内存大约是设备 RAM 的大小,但您必须注意释放它。使用 NDK 或 OpenGL 时可以使用这样的东西。 我不会说这很容易(因此可能值得作为评论但不是答案),但从你的描述听起来你可以创建一个带有本地方法的类,这些本地方法执行 malloc ()和免费()。如果你对 DalvikVM 如何管理内存的描述是正确的,这应该允许你绕过 DVM 检查(假设 Android 没有采取积极的措施来禁止它)。那么要解决的问题就是如何从 Java 访问该内存。 我假设 java 必须提供一个 inputStream 或一个新的字节数组,其中包含存储在本机内存中的数据。无论如何,我该如何实施这样的事情?是否已经有第三方库可以做到这一点? “但是,似乎在 Android 上,用于此的内存是在堆中使用的,而不是在本机内存中”——你是如何确定的? 【参考方案1】:您可以使用 NDK 实现一些东西,它会为您在本机堆中分配内存并使用 JNI 与其通信。本机部分在 C 中实现,并使用 malloc()
调用在本机堆中分配内存。不过,您仍然会受到每个进程堆最大值的影响。
这是另一种选择。与其尝试在自己的进程中使用本机堆,不如在另一个进程中使用 dalvik-heap。
创建一个服务并在另一个进程中运行该服务。您可以在服务和应用程序的其余部分之间来回发送数据。堆限制是每个进程,因此这有效地使您的应用程序可以使用的内存量翻倍。
当然,这可能对您的特定情况没有帮助,但很高兴知道此选项可用。
【讨论】:
mallocs 也受堆限制?!不仅我听说它是相反的,而且如果它没有帮助你为什么要建议它?另外,没有更简单的方法吗?使用多个进程可能无济于事,因为我需要相对快速地访问数据,并且不太推荐为此使用意图,尤其是在使用大字节数组时。不过很酷的提示。 mallocs 受本机堆限制,而不是 dalvik 堆限制(据我所知,但我还没有真正验证过——如果不正确,请见谅)。您可以使用对绑定服务的同步调用非常快速地从另一个进程获取数据。我已经构建了像这样工作的应用程序,并且工作得很好。 我可能不明白你的意思:本机堆限制是什么?关于服务,是否与从同一进程中获取数据一样快?以上是关于通过java使用本机内存的主要内容,如果未能解决你的问题,请参考以下文章