ما الذي يمكن أن يسبب SIGSEGV عند الاتصال NewObjectArray بـ JNI في Android؟

StackOverflow https://stackoverflow.com/questions/2113306

  •  22-09-2019
  •  | 
  •  

سؤال

لقد بدأت للتو العمل مع Android NDK ولكني أستمر في الحصول على SIGSEGV عندما يكون لدي هذه المكالمة في رمز C:

jobjectArray someStringArray;
someStringArray = (*env)->NewObjectArray(env, 10, 
(*env)->FindClass(env,"java/lang/String"),(*env)->NewStringUTF(env, ""));

قاعدة على كل المثال الذي يمكنني العثور عليه ، فإن الكود أعلاه صحيح ، لكنني أستمر في الحصول على sigsergv وكل شيء على ما يرام إذا تم التعليق على خط NewObjectArray. أي فكرة ما الذي يمكن أن يسبب مثل هذه المشكلة؟

هل كانت مفيدة؟

المحلول

هذا يبدو صحيحًا ، لذلك أعتقد أنك فعلت شيئًا آخر خاطئًا. أفترض أنك تعمل مع checkjni على؟ قد ترغب في تقسيم ذلك إلى خطوط متعددة: قم بإجراء FindClass وتحقق من قيمة الإرجاع ، والقيام بـ NewstringUtf وتحقق من قيمة الإرجاع ، ثم اتصل بـ NewObjectarray.

راجع للشغل ، قد ترغب في تمرير Null كحجة نهائية ؛ يتم استخدام هذا النمط من استخدام السلسلة الفارغة كقيمة افتراضية لكل عنصر من عناصر الصفيف (أعتقد أنه نسخة ولصقها من بعض وثائق الشمس وانتشرت من هناك) لكنها نادراً ما تكون مفيدة ، وهي مضيعة قليلاً. (ولا يتطابق مع سلوك "سلسلة جديدة [10] في جافا.)

نصائح أخرى

أعتقد أن أحد الأسباب المحتملة هو أنه في طريقة JNI على المدى الطويل ، يتم إحباط VM عندما ينفد من فتحات المرجع المحلية لكل تحديد الطائرات (عادة 512 فتحات في Android).

نظرًا لأن وظائف FindClass () و newtringutf () ستخصص المراجع المحلية ، إذا بقيت في طريقة JNI لفترة طويلة ، فإن VM لا يعرف ما إذا كان ينبغي إعادة تدوير مرجع محلي معين أم لا. لذلك يجب عليك استدعاء DeletelocalRef () بشكل صريح لإطلاق المراجع المحلية المكتسبة عندما لم تعد مطلوبة. إذا لم تقم بذلك ، فستشغل المراجع المحلية "الزومبي" فتحات في VM ، وينفد VM أثناء نفاد جميع الفتحات المرجعية المحلية.

في طريقة JNI على المدى القصير ، قد لا تكون هذه مشكلة بسبب جميع المراجع المحلية سيتم إعادة تدويرها عند الخروج من طريقة JNI.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top