【问题标题】:Andrjoid JNI simple for next return an errorAndrjoid JNI simple for next 返回错误
【发布时间】:2011-12-04 13:50:48
【问题描述】:
    jstring Java_com_example_hellojni_HelloJni_buildString(JNIEnv *env, jobject sThis){
        for (int i=0; i < 100000; i++){
              char* c=(char*)env->NewStringUTF("xx");
        }

        return env->NewStringUTF("test");
    }

12-04 14:46:36.399: 调试/dalvikvm(8086): 试图加载 lib /data/data/com.example.hellojni/lib/libhello-jni.so 0x405143d8 12-04 14:46:36.399:调试/dalvikvm(8086):添加了共享库 /data/data/com.example.hellojni/lib/libhello-jni.so 0x405143d8 12-04 14:46:36.431: WARN/dalvikvm(8086): ReferenceTable 溢出 (max=1024) 12-04 14:46:36.431: WARN/dalvikvm(8086): JNI local 中的最后 10 个条目 参考表:12-04 14:46:36.431: WARN/dalvikvm(8086): 1014: 0x4052b258 cls=Ljava/lang/字符串; (28 字节)12-04 14:46:36.431: 警告/dalvikvm(8086): 1015: 0x4052b298 cls=Ljava/lang/String; (28 字节)12-04 14:46:36.431:警告/dalvikvm(8086):1016:0x4052b2d8 cls=Ljava/语言/字符串; (28 字节)12-04 14:46:36.431: 警告/dalvikvm(8086): 1017: 0x4052b318 cls=Ljava/lang/String; (28 字节)12-04 14:46:36.431:警告/dalvikvm(8086):1018:0x4052b358 cls=Ljava/语言/字符串; (28 字节)12-04 14:46:36.431: 警告/dalvikvm(8086): 1019: 0x4052b398 cls=Ljava/lang/String; (28 字节)12-04 14:46:36.431:警告/dalvikvm(8086):1020:0x4052b3d8 cls=Ljava/语言/字符串; (28 字节)12-04 14:46:36.431: 警告/dalvikvm(8086): 1021: 0x4052b418 cls=Ljava/lang/String; (28 字节)12-04 14:46:36.431:警告/dalvikvm(8086):1022:0x4052b458 cls=Ljava/语言/字符串; (28 字节)12-04 14:46:36.431: 警告/dalvikvm(8086): 1023: 0x4052b498 cls=Ljava/lang/String; (28 字节) 12-04 14:46:36.431: WARN/dalvikvm(8086): JNI 本地参考 表格摘要(1024 个条目):12-04 14:46:36.431:WARN/dalvikvm(8086): Ljava/lang/类的1个; 236B 12-04 14:46:36.431: 警告/dalvikvm(8086):
Ljava/lang/类的1个; 284B 12-04 14:46:36.431: 警告/dalvikvm(8086):
Ljava/lang/类的1个; 572B 12-04 14:46:36.431:警告/dalvikvm(8086): Ljava/lang/String 的 1020; 28B (1020 唯一) 12-04 14:46:36.431: WARN/dalvikvm(8086): 1 of [Ljava/lang/String; 28B 12-04 14:46:36.431:WARN/dalvikvm(8086):内存直接由跟踪 refs 是 29680 字节 12-04 14:46:36.431: 错误/dalvikvm(8086): 失败 添加到 JNI 本地引用表(有 1024 个条目)12-04 14:46:36.431: 信息/dalvikvm(8086):“主要”prio=5 tid=1 RUNNABLE 12-04 14:46:36.431: 信息/dalvikvm(8086):| group="main" sCount=0 dsCount=0 obj=0x4001f1b8 self=0xcee8 12-04 14:46:36.431: INFO/dalvikvm(8086):
| sysTid=8086 nice=0 sched=0/0 cgrp=默认句柄=-1345006496 12-04 14:46:36.431:信息/dalvikvm(8086):在 com.example.hellojni.HelloJni.buildString(本机方法)12-04 14:46:36.431:信息/dalvikvm(8086):在 com.example.hellojni.HelloJni.onCreate(HelloJni.java:93)

很奇怪。如果我的 for next 看起来像这样:

for (int i=0; i < 100; i++){

然后一切正常。

如何重写此代码以运行具有大数字的 for next?

【问题讨论】:

  • 那个循环的目的到底是什么?
  • 对不起,我不明白你的问题。代码太多而文本太少。请准确描述您想要实现的目标以及您的问题。
  • 我想在 C 中为下一个循环运行一次大运行,从 JNI/Java 调用

标签: java android c java-native-interface


【解决方案1】:

如果您从 UI 线程调用此方法,那么它将暂停 1.4 分钟,并且 android 将关闭任何在 5 秒内没有响应的程序,这有助于您尝试使用 AsyncTask 或在另一个线程中执行此调用。

【讨论】:

  • 好的,我怎样才能重写它以不关闭android?异步?或线程?或如何? (c线程还是java?)
  • 如果你想在这个函数调用后访问 UI 线程使用 Handlers 或 AsyncTask
【解决方案2】:

您在一个 JNI 函数调用中分配了太多 Java 对象。 Dalvik 告诉您,您已经占用了整个对象引用表(在您的情况下为 1024 个对象)。因此,请使用 Java 数组或其他方式来存储您的数据。

每次调用 NewStringUTF 时,它都会将字符串复制到 Java“拥有”的内存中,并分配一个对象来管理字符串的 Java 版本(以及 Java 端使用的内存)。当您的引用超出范围时(在上面的示例中,当本机函数返回时)Java 分配的内存将被释放并且引用将被删除。

每次在 Java 端存储本地引用(以跟踪对象及其内存)时,它都会使用表中的一个槽。我不确定这张表有多大,但我很确定它相对较小,可能有 32 个条目。在您的情况下,它实际上是 1024 大(特定于实现),但无论哪种方式都有一个限制,如果您超过它,您将遇到您遇到的崩溃。

就如何解决这个问题而言,显而易见的规则是使用较少的本地引用。从您的代码 sn-p 不清楚 for 循环的含义是什么,但转换为 (char*) 表明根本缺乏对代码实际在做什么的理解。如果将其保留为 jstring,则可以选择随后调用 env->DeleteLocalRef( ... ) 来删除引用。无论如何,如果您想要实现某些特定目标,请提供更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    相关资源
    最近更新 更多