2011-12-04 11 views
0
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月4日14:46:36.399:DEBUG/dalvikvm(8086): /data/data/com.example.hellojni/lib/ libにロードしようとしlibhello-jni.so 0x405143d8 12-04 14:46:36.399:DEBUG/dalvikvm(8086):共有ライブラリを追加しました /data/data/com.example.hellojni/lib/libhello-jni.so 0x405143d8 12-04 WARN/dalvikvm(8086):JNIローカルの最後の10個のエントリ 参照表:12 - 04(参考):14/46:36.431:WARN/dalvikvm(8086):ReferenceTableオーバーフロー(最大= 1024) 12-04 14:46:36.431:WARN/dalvikvm 14:46:36.431:WARN/dalvikvm(8086):1014: 0x4052b258 cls = Ljava/lang/String; (28バイト)12-04 14:46:36.431: WARN/dalvikvm(8086):1015:0x4052b298 cls = Ljava/lang/String; (28 バイト)12-04 14:46:36.431:WARN/dalvikvm(8086):1016:0x4052b2d8 cls = Ljava/lang/String; (28バイト)12-04 14:46:36.431: WARN/dalvikvm(8086):1017:0x4052b318 cls = Ljava/lang/String; (28 バイト)12-04 14:46:36.431:WARN/dalvikvm(8086):1018:0x4052b358 cls = Ljava/lang/String; (28バイト)12-04 14:46:36.431: WARN/dalvikvm(8086):1019:0x4052b398 cls = Ljava/lang/String; (28 バイト)12-04 14:46:36.431:WARN/dalvikvm(8086):1020:0x4052b3d8 cls = Ljava/lang/String; (28バイト)12-04 14:46:36.431: WARN/dalvikvm(8086):1021:0x4052b418 cls = Ljava/lang/String; (28 バイト)12-04 14:46:36.431:WARN/dalvikvm(8086):1022:0x4052b458 cls = Ljava/lang/String; (28バイト)12-04 14:46:36.431: WARN/dalvikvm(8086):1023:0x4052b498 cls = Ljava/lang/String; (1024エントリ):12-04 14:46:36.431:WARN/dalvikvm(8086): 1 Ljava/lang/Classの236B 12-04 14:46:36.431:WARN/dalvikvm(8086):
Ljava/lang/Classの1つ。 284B 12-04 14:46:36.431:WARN/dalvikvm(8086):
Ljava/lang/Classの1つ。 572B 12-04 14:46:36.431:WARN/dalvikvm(8086): Ljava/lang/Stringの1020; 28B(1020ユニーク)12-04 14:46:36.431: WARN/dalvikvm(8086):1の[Ljava/lang/String; 28B 12-04 14:46:36.431:WARN/dalvikvm(8086):追跡されたメモリによって直接保持されているメモリ refsは29680バイト12-04 14:46:36.431:ERROR/dalvikvm(8086):失敗 JNIローカルに追加refテーブル(1024エントリあり)12-04 14:46:36.431: INFO/dalvikvm(8086): "メイン" prio = 5 tid = 1 RUNNABLE 12-04 14:46:36.431: INFO/dalvikvm :|グループ= "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:INFO/dalvikvm(8086): でcom.example.hellojni.HelloJni.buildString(ネイティブメソッド) 12月4日 14:46:36.431:INFO/dalvikvm(8086): com.example.hellojni.HelloJni.onCreate(HelloJni.java:93)でAndrjoid JNIの単純なエラー

奇妙な。次のような場合は

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

となります。

for the nextを大きい数字で実行するには、どうすればこのコードを書き直すことができますか?

+0

ループの目的は何ですか? – Mat

+0

申し訳ありませんが、私はあなたの質問を得ることはありません。多くのコードとあまりにも少ないテキスト。達成したいことと問題の内容を正確に記述してください。 – Robert

+0

私はJNI/Javaから呼び出されたCの次のサイクルのために大きな実行をしたいと思います。 – lacas

答えて

0

UIスレッドからこのメソッドを呼び出す場合は、1の間一時停止します。4分、アンドロイドは5秒間応答しないプログラムを終了します。これは、AsyncTaskを使用するか、別のスレッドでこの呼び出しを実行するのに役立ちます。

+0

ok、どうすればアンドロイドを閉じないように書き換えることができますか?非同期?またはスレッド?またはどのように? (cスレッドまたはjava?) – lacas

+0

この関数呼び出しの後にUIスレッドにアクセスする場合は、ハンドラまたはAsyncTaskを使用します。 – confucius

+0

スレッドクラスを使用すると、UIスレッドにアクセスできません。 – confucius

0

1つのJNI関数呼び出しで多すぎるJavaオブジェクトを割り当てます。 Dalvikは、オブジェクト参照テーブル全体(あなたの場合は1024個のオブジェクト)を占有していることを伝えます。したがって、Java配列や別の方法でデータを格納してください。

NewStringUTFを呼び出すたびに、文字列をJavaが所有するメモリにコピーし、Javaバージョンの文字列(およびJava側で使用されるメモリ)を管理するオブジェクトを割り当てます。参照がスコープから外れると(上記の例では、ネイティブ関数が返ってくると)、Javaが割り当てたメモリは解放され、参照は破棄されます。

ローカル参照が(オブジェクトとそのメモリを追跡するために)Java側に格納されるたびに、テーブル内のスロットが使用されます。私はこのテーブルの大きさがどれほど大きいか確信が持てませんが、それは比較的小さく、おそらく32のエントリであると確信しています。あなたの場合、それは実際には1024ビッグ(実装固有)ですが、いずれかの方法で限界があります。それを超えると、あなたが経験しているクラッシュを得るでしょう。

この問題を回避する方法については、ローカル参照を少なくすることが明らかです。あなたのコードスニペットから、forループが何をしているのかははっきりしませんが、(char *)へのキャストは、コードが実際に何をしているのかを理解できていないことを示唆しています。 jstringとして保存した場合、env-> DeleteLocalRef(...)を呼び出して参照を削除することができます。とにかく、あなたが達成しようとしている具体的なことがあれば、さらに情報を提供してください。