java - 避免 JNI C 与 Java 之间的内存泄漏

标签 java android memory-management memory-leaks java-native-interface

找到了一种将复杂模型(带有子对象的对象和带有对象项的 ArrayList)从 C 返回到 Java 的方法。但我还有另一个问题:内存泄漏。

目前,我正在处理的代码正在解析数据(在 C 上),并且应该将解析的数据返回到 Java 类。

主 Java 类包含更多 Java 类(整数、字符串、 boolean 值、Obj、对象的 ArrayList),并且我使用此模式为对象实例返回解析的数据:

    // Instance:LyricsLineVo
    jclass findClsLyricsLine = (*env)->FindClass(env, "com/example/jni/vo/LyricsLineVo");
    jmethodID initLyricsLine = (*env)->GetMethodID (env, findClsLyricsLine, initMethod,"()V");
    jobject objLyricsLine = (*env)->NewObject(env, findClsLyricsLine, initLyricsLine);
    jclass classLyricsLine = (*env)->GetObjectClass(env, objLyricsLine);

代码太长,我不知道是否应该将其他对象分离到另一个函数,然后将解析的数据传递给每个不同的函数,我认为这会消耗更多内存,而且我已经在释放已用内存方面遇到了问题的。

我阅读了一些有关如何释放空间的方法:

Memory leak using JNI to retrieve String's value from Java code

Memory leak when calling java code from C using JNI

但是应用这些还不够。它只能允许一次数据解析,但之后我的程序就崩溃了。

还有其他推荐的代码可以减少内存使用吗?

我在下面添加我的错误日志:

    07-11 19:23:31.640: WARN/dalvikvm(301): ReferenceTable overflow (max=512)
    07-11 19:23:31.650: WARN/dalvikvm(301): Last 10 entries in JNI local reference table:
    07-11 19:23:31.650: WARN/dalvikvm(301): 502: 0x44df0930 cls=Ljava/lang/Class; 'Lcom/demo/project/vo/DurationVo;' (172 bytes)
    07-11 19:23:31.650: WARN/dalvikvm(301): 503: 0x44df51a8 cls=Lcom/demo/project/vo/DurationVo; (20 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 504: 0x44df0930 cls=Ljava/lang/Class; 'Lcom/demo/project/vo/DurationVo;' (172 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 505: 0x4002afc8 cls=Ljava/lang/Class; 'Ljava/util/ArrayList;' (172 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 506: 0x44df5280 cls=Ljava/util/ArrayList; (28 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 507: 0x44df0338 cls=Ljava/lang/Class; 'Lcom/demo/project/vo/MeasureTrackPairVo;' (172 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 508: 0x44df52a0 cls=Lcom/demo/project/vo/MeasureTrackPairVo; (28 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 509: 0x44df0338 cls=Ljava/lang/Class; 'Lcom/demo/project/vo/MeasureTrackPairVo;' (172 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 510: 0x4002afc8 cls=Ljava/lang/Class; 'Ljava/util/ArrayList;' (172 bytes)
    07-11 19:23:31.660: WARN/dalvikvm(301): 511: 0x44df5320 cls=Ljava/util/ArrayList; (28 bytes)
    07-11 19:23:31.680: WARN/dalvikvm(301): JNI local reference table summary (512 entries):
    07-11 19:23:31.690: WARN/dalvikvm(301): 322 of Ljava/lang/Class; 172B (11 unique)
    07-11 19:23:31.690: WARN/dalvikvm(301): 7 of Ljava/lang/Integer; 12B (7 unique)
    07-11 19:23:31.690: WARN/dalvikvm(301): 10 of Ljava/lang/String; 28B (10 unique)
    07-11 19:23:31.690: WARN/dalvikvm(301): 33 of Ljava/util/ArrayList; 28B (33 unique)
    07-11 19:23:31.690: WARN/dalvikvm(301): 1 of Lcom/demo/project/vo/HeaderVo; 60B
    07-11 19:23:31.700: WARN/dalvikvm(301): 1 of Lcom/demo/project/vo/LyricsVo; 20B
    07-11 19:23:31.700: WARN/dalvikvm(301): 1 of Lcom/demo/project/vo/LyricsLineVo; 20B
    07-11 19:23:31.700: WARN/dalvikvm(301): 18 of Lcom/demo/project/vo/MeasureHeaderVo; 36B (18 unique)
    07-11 19:23:31.710: WARN/dalvikvm(301): 1 of Lcom/demo/project/vo/TrackHeaderVo; 60B
    07-11 19:23:31.710: WARN/dalvikvm(301): 14 of Lcom/demo/project/vo/MeasureTrackPairVo; 28B (14 unique)
    07-11 19:23:31.710: WARN/dalvikvm(301): 52 of Lcom/demo/project/vo/BeatVo; 60B (52 unique)
    07-11 19:23:31.710: WARN/dalvikvm(301): 52 of Lcom/demo/project/vo/DurationVo; 20B (52 unique)
    07-11 19:23:31.710: WARN/dalvikvm(301): Memory held directly by native code is 8540 bytes
    07-11 19:23:31.720: ERROR/dalvikvm(301): Failed adding to JNI local ref table (has 512 entries)

最佳答案

我正在使用

      (*env)->DeleteLocalRef(env, classLyricsLine);
      (*env)->DeleteLocalRef(env, objLyricsLine);
      (*env)->DeleteLocalRef(env, findClsLyricsLine);

而且似乎已经解决了ReferenceTable溢出的问题。但是,我收到另一个错误,不是因为有太多对象实例,而是因为访问数据。

     Song *song  // struct.
     ....
     song->measureTracks[m][n].beats[0].notes[0].noteEffects->bend->bendPoints

错误日志示例:

        07-14 16:57:00.725: INFO/DEBUG(28): Build fingerprint: 'generic/sdk/generic/:2.1-update1/ECLAIR/35983:eng/test-keys'
        07-14 16:57:00.725: INFO/DEBUG(28): pid: 297, tid: 307  >>> com.synapticstuff.guitartabs <<<
        07-14 16:57:00.735: INFO/DEBUG(28): signal 11 (SIGSEGV), fault addr 0000001c
        07-14 16:57:00.735: INFO/DEBUG(28): r0 00000034  r1 00127f28  r2 00000000  r3 00000000
        07-14 16:57:00.735: INFO/DEBUG(28): r4 80a06ad4  r5 ad02cab9  r6 41878d20  r7 41867de4
        07-14 16:57:00.735: INFO/DEBUG(28): r8 46d68d50  r9 41867ddc  10 41867dc4  fp 00139838
        07-14 16:57:00.735: INFO/DEBUG(28): ip ad080214  sp 46d68a30  lr ad03bad1  pc 80a02bb2  cpsr 00000030
        07-14 16:57:00.905: INFO/DEBUG(28): #00  pc 00002bb2  /data/data/com.synapticstuff.guitartabs/lib/libgpparser.so
        07-14 16:57:00.915: INFO/DEBUG(28): #01  pc 0000f1f4  /system/lib/libdvm.so
        07-14 16:57:00.915: INFO/DEBUG(28): #02  pc 00038018  /system/lib/libdvm.so
        07-14 16:57:00.925: INFO/DEBUG(28): #03  pc 000316a2  /system/lib/libdvm.so
        07-14 16:57:00.925: INFO/DEBUG(28): #04  pc 0003d31c  /system/lib/libdvm.so
        07-14 16:57:00.925: INFO/DEBUG(28): #05  pc 00013f58  /system/lib/libdvm.so
        07-14 16:57:00.925: INFO/DEBUG(28): #06  pc 00019888  /system/lib/libdvm.so
        07-14 16:57:00.935: INFO/DEBUG(28): #07  pc 00018d5c  /system/lib/libdvm.so
        07-14 16:57:00.935: INFO/DEBUG(28): #08  pc 0004d6d0  /system/lib/libdvm.so
        07-14 16:57:00.945: INFO/DEBUG(28): #09  pc 0004d702  /system/lib/libdvm.so
        07-14 16:57:00.945: INFO/DEBUG(28): #10  pc 00041c78  /system/lib/libdvm.so
        07-14 16:57:00.945: INFO/DEBUG(28): #11  pc 00010000  /system/lib/libc.so
        07-14 16:57:00.955: INFO/DEBUG(28): #12  pc 0000fad4  /system/lib/libc.so
        07-14 16:57:00.955: INFO/DEBUG(28): code around pc:
        07-14 16:57:00.975: INFO/DEBUG(28): 80a02ba0 68d918d3 1c139a2e 189b009b 18cb00db
        07-14 16:57:00.975: INFO/DEBUG(28): 80a02bb0 7f1b6a5b 9b05931c 23bc681a 58d5005b
        07-14 16:57:00.975: INFO/DEBUG(28): 80a02bc0 99259805 447b4b8c 4b8c1c1a 47a8447b
        07-14 16:57:00.975: INFO/DEBUG(28): code around lr:
        07-14 16:57:00.975: INFO/DEBUG(28): ad03bac0 18282200 f890f7f9 21079802 ffcef004
        07-14 16:57:01.042: INFO/DEBUG(28): ad03bad0 1c30b005 46c0bdf0 000444c8 fffe57c4
        07-14 16:57:01.045: INFO/DEBUG(28): ad03bae0 fffea17e fffea125 6900b5f0 1c0db087
        07-14 16:57:01.045: INFO/DEBUG(28): stack:
        07-14 16:57:01.055: INFO/DEBUG(28): 46d689f0  00129300  [heap]
        07-14 16:57:01.055: INFO/DEBUG(28): 46d689f4  44e0eab8  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.065: INFO/DEBUG(28): 46d689f8  80a056d8  /data/data/com.synapticstuff.guitartabs/lib/libgpparser.so
        07-14 16:57:01.065: INFO/DEBUG(28): 46d689fc  ad02cb49  /system/lib/libdvm.so
        07-14 16:57:01.065: INFO/DEBUG(28): 46d68a00  ad038f65  /system/lib/libdvm.so
        07-14 16:57:01.076: INFO/DEBUG(28): 46d68a04  00129300  [heap]
        07-14 16:57:01.076: INFO/DEBUG(28): 46d68a08  44e0eb68  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.076: INFO/DEBUG(28): 46d68a0c  ad02a095  /system/lib/libdvm.so
        07-14 16:57:01.076: INFO/DEBUG(28): 46d68a10  80a06ad4  /data/data/com.synapticstuff.guitartabs/lib/libgpparser.so
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a14  80a05090  /data/data/com.synapticstuff.guitartabs/lib/libgpparser.so
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a18  ad02d935  /system/lib/libdvm.so
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a1c  80a06ad4  /data/data/com.synapticstuff.guitartabs/lib/libgpparser.so
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a20  ad02cab9  /system/lib/libdvm.so
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a24  41878d20  /dev/ashmem/dalvik-LinearAlloc (deleted)
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a28  df002777
        07-14 16:57:01.085: INFO/DEBUG(28): 46d68a2c  e3a070ad
        07-14 16:57:01.095: INFO/DEBUG(28): #00 46d68a30  00000000
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a34  3fe00000
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a38  44dfe710  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a3c  44dfe9a8  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a40  44dfe1b0  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a44  00129300  [heap]
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a48  44dfede8  /dev/ashmem/mspace/dalvik-heap/2 (deleted)
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a4c  ffffffff
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a50  00000073
        07-14 16:57:01.095: INFO/DEBUG(28): 46d68a54  00000009
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a58  46d68cc4
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a5c  afe38e08  /system/lib/libc.so
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a60  46d68aac
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a64  fffffff7
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a68  ad06aae8  /system/lib/libdvm.so
        07-14 16:57:01.105: INFO/DEBUG(28): 46d68a6c  ad07ff50  /system/lib/libdvm.so

现在看来问题是什么? 我已经准备好了所有对象实例,但每次我尝试使用带有数据的实际结构歌曲时,如果距离太远,它就会崩溃。即使我只得到结构的一部分:

    NoteEffects *noteEffects = song->measureTracks[m][n].beats[0].notes[0].noteEffects
    // then use noteEffects.bend

关于java - 避免 JNI C 与 Java 之间的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6594018/

相关文章:

java - Spring Security表单登录属性的动态配置

java - 更新按钮颜色

android - 在 Android 设备上显示非英语(特别是印地语)字符

android - 添加 Canvas - Android

c++ - memset, memcpy with new 运算符

iphone - 另一个 "message sent to deallocated instance"

java - 将字符串分解为子字符串,Android

java - 如何在android中禁用系统对话框窗口或弹出窗口?

android - 如何在线上传数据库并将该数据库中的数据接收到android应用程序中?

c++ - 物理内存量随着我释放 block 而增加