`

jna ByteBuffer的没有得到释放,导致C堆中耗尽内存

    博客分类:
  • jni
jni 
阅读更多
http://codego.net/99906/


说,我怎么JNA和Java直接拨款的理解充其量是内脏,所以我试图描述我对什么事情的理解开始。任何更正,除了反应将是巨大的... 我跑了混合了Java和C JNA本地应用程序和正在运行进行的跨与Java垃圾收集器不能自由引用的直接分配一个可重复的问题,导致了C堆耗尽 我敢肯定,我的C应用程序是不是配置问题的来源,因为我传递一个java.nio.ByteBuffer进入我的C代码 CodeGo.net,修改缓冲区中,然后在访问我的Java函数的结果。我有一个单一的malloc和一个单一的对应free每个函数调用过程中,但经过反复运行代码Java中的malloc最终将失败。 下面是一个代码轻视集,展示的问题-现实我试图拨出约在C堆函数调用时16至32MB。 我的Java代码的作用,如:
public class MyClass{
public void myfunction(){
  ByteBuffer foo = ByteBuffer.allocateDirect(1000000);
  MyDirectAccessLib.someOp(foo, 1000000);
  System.out.println(foo.get(0));
}
}
public MyDirectAccessLib{
static {
  Native.register("libsomelibrary");
}
public static native void someOp(ByteBuffer buf, int size);
}
然后,我的C代码可能是这样:
#include <stdio.h>
#include <stdlib.h>
void someOp(unsigned char* buf, int size){
unsigned char *foo;
foo = malloc(1000000);
if(!foo){
  fprintf(stderr, "Failed to malloc 1000000 bytes of memory\n");
  return;
}
free(foo);
buf[0] = 100;
}
trouble的是调用这个函数反复Java堆是稳定的(它生长缓慢),但C函数最终不能分配任何在较高的水平,我相信这就是Java是C堆中,但不清理的ByteBuffer指向在后在Java ByteBuffer的目的是比较小的。 据我发现在我的函数手动运行GC将提供所需的清理工作,但是这似乎是一个既可怜的想法,一个贫穷的解决方案。 我该如何处理这个问题更好,这样的ByteBuffer的空间被适当地释放,我的C堆空间被控制? 是我对问题的理解不正确(在那里,我跑不正确)? 编辑:缓冲区大小,以更好地反映我的实际应用,我在分配给图像约3000X2000 ...
本文地址 :CodeGo.net/99906/

-------------------------------------------------------------------------------------------------------------------------
1. 我认为你已经正确的诊断:你永远不会耗尽Java堆的,因此JVM没有垃圾收集,并且映射缓冲区不会被释放。您手动运行GC的时候没有问题,这似乎证实了这一点。你也可以打开详细日志记录集合作为一个二次确认。 所以,你可以做什么?嗯,我想尝试的优先件事是要保持初始JVM堆大小小,使用-这可能的问题 CodeGo.net,如果你的程序是不断的小分配上的Java堆,因为它会更频繁地运行GC。 我最好的PMAP工具(或任何等值是在Windows上),研究地图。这有可能是你的C堆中,通过分配可变大小的缓冲区。如果是这样的话,那么你会看到每一个大的虚拟地图,用“匿名”块之间的差距。而解决办法是分配常数大小的块是大于你所需要的。
2. 你实际上是在面临Java VM的一个已知的bug。在bug报告中列出的最佳解决方法是: “该-XX:。MaxDirectMemorySize=选项可以限制使用量来分配,将这个限制被超过一个完整的GC,从而挑起参考处理和未引用的缓冲区释放的尝试” 其他可能的解决方法包括: 偶尔插入显式System.gc()的调用,以确保直接缓冲区 减轻年轻一代的尺寸给力更频繁的GC。 明确集中直接缓冲区在应用程序级别。 如果你真的想依靠直接字节缓冲区,那么我会建议汇集在应用程序级别。根据您的应用程序,你甚至可能只是高速缓存和缓冲区(小心多线程)。
3. 我怀疑你的问题是由于直接字节缓冲区。他们可以在Java堆之外分配。 如果你频繁调用,以及分配小的缓冲区每个模式可能不是一个很好的适合直接缓冲区。 为了找出问题所在,我会切换到(Java)的堆中分配的缓冲区(该allocate替代方法allocateDirect。如果让问题消失,你已经找到了罪魁祸首。接下来的问题将是一个直接字节缓冲区是否有任何优势性能,明智的。如果不是(我猜想,事实并非如此),那么你就不需要担心如何正确清理。
4. 如果你用完的GC会自动触发。但是,如果你用完了GC的,则不会触发(在Sun的JVM,至少),你只得到一个OutOfMemoryError错误即使GC会释放我发现你必须在这种情况下手动触发GC。 一个更好的解决方案可能是对的ByteBuffer所以你永远不需要重新acllocate的ByteBuffers。
5. 要释放的直接Buffer的[1]的内存,你的JNI。 该函数GetDirectBufferAddress(JNIEnv* env, jobject buf)[3]从JNI 6的API可以获取指针的Buffer然后在标准free(void *ptr)命令上的指针自由 而不是编写如C代码从Java调用该函数,你JNA的Native.getDirectBufferPointer(Buffer)[6] 之后剩下的唯一一件事就是放弃了所有引用Buffer对象。那么Java的垃圾回收将释放Buffer例如,因为它与任何其它非引用的对象。 请注意,直接Buffer不一定映射1:1到一个区域中。例如JNI的API有NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity)[7]。因此,你应该只Buffer你知道是一对一的跟的,分配区域 我也不知道,如果你可以free直接Buffer通过Java的创建ByteBuffer.allocateDirect(int)[8]为完全如上述的理由。当交给了新的直接也可能是JVM或Java平台的具体细节是否泳池或做1:1的内存分配Buffer秒。 这里遵循从我的图书馆就直接稍加修改的片段ByteBuffer[9]处理(使用JNANative[10]和Pointer[11]类):
/**
* Allocate native memory and associate direct {@link ByteBuffer} with it.
*
* @param bytes - How many bytes of memory to allocate for the buffer
* @return The created {@link ByteBuffer}.
*/
public static ByteBuffer allocateByteBuffer(int bytes) {
  long lPtr = Native.malloc(bytes);
  if (lPtr == 0) throw new Error(
   "Failed to allocate direct byte buffer memory");
  return Native.getDirectByteBuffer(lPtr, bytes);
}
/**
* Free native memory inside {@link Buffer}.
* <p>
* Use only buffers whose memory region you know to match one to one
* with that of the underlying allocated memory region.
*
* @param buffer - Buffer whose native memory is to be freed.
* The class instance will remain. Don't use it anymore.
*/
public static void freeNativeBufferMemory(Buffer buffer) {
  buffer.clear();
  Pointer javaPointer = Native.getDirectBufferPointer(buffer);
  long lPtr = Pointer.nativeValue(javaPointer);
  Native.free(lPtr);
}
分享到:
评论

相关推荐

    使用JNA替代JNI调用DLL,并解决内存溢出问题

    请C++同事帮忙写个dll程序,dll去解析开发平台输出的二进制流数据,上层应用平台调用dll得到json报文,然后再去做一些业务处理。 那现在上层应用面临的问题:访问java外部功能接口实现方式(即调用dll)怎么选择及...

    深入解析JNA—模拟C语言结构体

    深入解析JNA—模拟C语言结构体

    jna-5.0.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.4.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.6.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.5.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-4.5.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-4.4.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-4.0.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.10.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-4.5.2.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    利用jna在java下调用c语言库文件

    在此编了一个利用jna在java平台下调用c语言动态链接库的例子,c++代码也已经提供,java代码已经调试通过。

    jna-4.3.0-API文档-中文版.zip

    赠送jar包:jna-4.3.0.jar; 赠送原API文档:jna-4.3.0-javadoc.jar; 赠送源代码:jna-4.3.0-sources.jar; 赠送Maven依赖信息文件:jna-4.3.0.pom; 包含翻译后的API文档:jna-4.3.0-javadoc-API文档-中文(简体)版...

    jna-4.1.0-API文档-中文版.zip

    赠送jar包:jna-4.1.0.jar; 赠送原API文档:jna-4.1.0-javadoc.jar; 赠送源代码:jna-4.1.0-sources.jar; 赠送Maven依赖信息文件:jna-4.1.0.pom; 包含翻译后的API文档:jna-4.1.0-javadoc-API文档-中文(简体)版...

    jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包

    jna-4.5.1 , jna-4.5.1-sources , jna-platform-4.5.1 jar包 JNA全称Java Native Access,是一个...开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

    jna-4.1.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.2.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    JNA的API文档

    JNA的API文档

    jna-3.5.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

    jna-5.12.0.jar中文文档.zip

    注:下文中的 *** 代表文件名中的版本号。 # 【jna-***.jar中文文档.zip】 中包含: 中文文档:【jna-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【jna-***.jar下载地址(官方地址+国内镜像地址).txt...

Global site tag (gtag.js) - Google Analytics