Android रनटाइम (ART) पर ऐप्लिकेशन के काम करने के तरीके की पुष्टि करना

Android रनटाइम (ART), Android पर चलने वाले डिवाइसों के लिए डिफ़ॉल्ट रनटाइम है 5.0 (एपीआई लेवल 21) और उसके बाद के वर्शन. इस रनटाइम में कई सुविधाएं मिलती हैं Android प्लैटफ़ॉर्म और ऐप्लिकेशन की परफ़ॉर्मेंस और आसानी से काम करने की क्षमता को बेहतर बनाता है. ART की नई सुविधाओं के बारे में ज़्यादा जानकारी पाने के लिए ART है.

हालांकि, Delvik पर काम करने वाली कुछ तकनीकें, ART पर काम नहीं करती. यह दस्तावेज़ आपको किसी मौजूदा माइग्रेशन के दौरान ध्यान देने वाली चीज़ों के बारे में जानने देता है के साथ काम करने की अनुमति देता है. ज़्यादातर ऐप्लिकेशन को सिर्फ़ डिवाइस पर काम करते समय काम करना चाहिए एआरटी.

कचरा इकट्ठा करने (जीसी) से जुड़ी समस्याएं हल करना

Delvik के तहत, ऐप्लिकेशन को अक्सर कॉल करने के दौरान गार्बेज कलेक्शन (जीसी) के बारे में प्रॉम्प्ट दिखाने के लिए System.gc(). यह ऐसा होना चाहिए यह सुविधा ART के साथ बहुत कम ज़रूरी है, खास तौर पर तब, जब कचरा इकट्ठा करने की सुविधा लागू की जा रही हो GC_FOR_ALLOC-टाइप को रोकने के लिए या फ़्रैगमेंटेशन कम करने के लिए. आपके पास यह पुष्टि करने का विकल्प है कि कौनसा रनटाइम इस्तेमाल किया जा रहा है System.getProperty("java.vm.version") पर कॉल करके. अगर ART का इस्तेमाल किया जा रहा है, तो प्रॉपर्टी का मान "2.0.0" या इससे ज़्यादा है.

ART, समवर्ती कॉपी (सीसी) कलेक्टर का इस्तेमाल करता है, जो Java हीप को एक साथ कॉम्पैक्ट करता है. इसलिए, आपको ऐसी तकनीकों का इस्तेमाल करने से बचना चाहिए जो कॉम्पैक्ट जीसी (जैसे कि ऑब्जेक्ट में पॉइंटर सेव करना) के साथ काम न करते हों इंस्टेंस डेटा). यह विशेष रूप से उन ऐप्लिकेशन के लिए महत्वपूर्ण है जो जावा नेटिव इंटरफ़ेस (जेएनआई). ज़्यादा जानकारी के लिए, जेएनआई समस्याओं से बचाव करना लेख पढ़ें.

JNI समस्याओं से बचाव करना

ART का JNI, डाल्विक के मुकाबले थोड़ा सख्त है. यह एक अच्छा आइडिया है ताकि आम समस्याओं को पकड़ने के लिए CheckJNI मोड का इस्तेमाल किया जा सके. अगर आपका ऐप्लिकेशन C/C++ का इस्तेमाल करता है तो आपको निम्न लेख पढ़ना चाहिए:

डीबग करना CheckJNI के साथ Android JNI

कूड़ा इकट्ठा करने से जुड़ी समस्याओं के लिए जेएनआई कोड की जांच करना

एक साथ कॉपी करने की सुविधा (सीसी) कलेक्टर, मेमोरी में मौजूद ऑब्जेक्ट को कंप्रेस किए जाने के लिए इधर-उधर ले जा सकता है. अगर C/C++ कोड का इस्तेमाल किया जा रहा है, तो ऐसी कार्रवाइयां करेंगे जो कॉम्पैक्ट GC से मेल नहीं खातीं. हमने बेहतर बनाया है CheckJNI, कुछ संभावित समस्याओं का पता लगाता है. इनकी जानकारी जेएनआई में दी गई है ICS में स्थानीय रेफ़रंस के बदलाव).

खास तौर पर, इन चीज़ों पर ध्यान देने की ज़रूरत है: Get...ArrayElements() और Release...ArrayElements() फ़ंक्शन. नॉन-कॉम्पैक्ट GC वाले रनटाइम में, Get...ArrayElements() फ़ंक्शन आम तौर पर असल मेमोरी की मदद से अरे ऑब्जेक्ट का बैक अप लिया जा रहा है. यदि आप इनमें से किसी एक अरे एलिमेंट दिखाता है, तो अरे ऑब्जेक्ट अपने-आप बदल जाता है (और आर्ग्युमेंट आम तौर पर, Release...ArrayElements() तक को अनदेखा कर दिया जाता है). हालांकि, अगर कॉम्पैक्ट जीसी का इस्तेमाल किया जा रहा है, Get...ArrayElements() फ़ंक्शन मेमोरी की एक कॉपी दिखाएं. अगर जीसी को छोटा करते समय रेफ़रंस का गलत इस्तेमाल किया जाता है, तो तो इसकी वजह से मेमोरी खराब हो सकती है या दूसरी समस्याएं हो सकती हैं. उदाहरण के लिए:

  • अगर आपने रिटर्न किए गए अरे एलिमेंट में कोई बदलाव किया है, तो आपको काम पूरा करने के बाद, सही Release...ArrayElements() फ़ंक्शन होना चाहिए, ताकि यह पक्का किया जा सके कि आपने जो बदलाव किए हैं वे बुनियादी जानकारी वाले पेज पर सही तरीके से कॉपी किए गए हैं अरे ऑब्जेक्ट को इकट्ठा करता है.
  • मेमोरी अरे के एलिमेंट को रिलीज़ करते समय, आपको सही मोड पर निर्भर करता है, जो इस बात पर निर्भर करता है कि आपने क्या बदलाव किए हैं:
    • अगर आपने अरे एलिमेंट में कोई बदलाव नहीं किया है, तो JNI_ABORT मोड, जो कॉपी किए बिना मेमोरी को रिलीज़ करता है दिए गए अरे ऑब्जेक्ट में वापस बदल जाता है.
    • अगर आपने कलेक्शन में बदलाव किए हैं और आपको किसी रेफ़रंस की ज़रूरत नहीं है इसके अलावा, 0 कोड का इस्तेमाल करें. इससे अरे ऑब्जेक्ट को अपडेट किया जाता है और यह फ़्री होता है मेमोरी की कॉपी).
    • अगर आपने उस कलेक्शन में बदलाव किए हैं जिसके लिए आपको बदलाव करना है और अरे की कॉपी बनाए रखने के लिए, JNI_COMMIT का इस्तेमाल करें. इससे यह अपडेट हो जाएगा मौजूदा अरे ऑब्जेक्ट को कॉपी करता है और कॉपी को बनाए रखता है).
  • जब आप Release...ArrayElements() को कॉल करें, तो उसी आइटम को वापस करें वह पॉइंटर जो मूल रूप से Get...ArrayElements() से लौटाया गया था. इसके लिए उदाहरण के लिए, ओरिजनल पॉइंटर को बढ़ाना या अरे एलिमेंट दिखाता है) फिर बढ़ा हुआ पॉइंटर को Release...ArrayElements(). इस बदले गए पॉइंटर को पास करने से यह हो सकता है को खाली करने में गड़बड़ी होती है, जिसकी वजह से मेमोरी खराब हो जाती है.

गड़बड़ी ठीक करना

ART का JNI कई मामलों में गलतियां दिखाता है, लेकिन डाल्विक नहीं करता. (एक बार CheckJNI की मदद से टेस्ट करके, ऐसे कई मामलों का पता लगाया जा सकता है.)

उदाहरण के लिए, अगर RegisterNatives को किसी ऐसे तरीके से कॉल किया जाता है जो मौजूद नहीं है (शायद इसलिए क्योंकि इस विधि को ProGuard), ART अब सही तरीके से NoSuchMethodError थ्रो करता है:

08-12 17:09:41.082 13823 13823 E AndroidRuntime: FATAL EXCEPTION: main
08-12 17:09:41.082 13823 13823 E AndroidRuntime: java.lang.NoSuchMethodError:
    no static or non-static method
    "Lcom/foo/Bar;.native_frob(Ljava/lang/String;)I"
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.nativeLoad(Native Method)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.doLoad(Runtime.java:421)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.Runtime.loadLibrary(Runtime.java:362)
08-12 17:09:41.082 13823 13823 E AndroidRuntime:
    at java.lang.System.loadLibrary(System.java:526)

अगर RegisterNatives है, तो ART एक गड़बड़ी (लॉगकैट में दिखाई देता है) भी लॉग करता है बिना किसी पद्धति के कॉल किया गया:

W/art     ( 1234): JNI RegisterNativeMethods: attempt to register 0 native
methods for <classname>

साथ ही, JNI, GetFieldID() और GetStaticFieldID() ने अब NoSuchFieldError को सही तरीके से बॉल फेंका शून्य को लौटाने के बजाय. इसी तरह, GetMethodID() और GetStaticMethodID() ने अब NoSuchMethodError को सही तरीके से थ्रो किया. इसकी वजह से, हो सकता है कि CheckJNI काम न करे. इन अपवादों या नेटिव कोड के Java कॉलर को दिए जाने वाले अपवाद. इससे यह और CheckJNI मोड के साथ एआरटी के हिसाब से काम करने वाले ऐप्लिकेशन की जांच करना खास तौर पर ज़रूरी है.

ART, जेएनआई CallNonvirtual...Method() तरीकों का इस्तेमाल करने वाले उपयोगकर्ताओं से उम्मीद करता है (जैसे कि CallNonvirtualVoidMethod()) तरीके की घोषणा का इस्तेमाल करने के लिए क्लास, न कि सब-क्लास, जैसा कि JNI स्पेसिफ़िकेशन के मुताबिक ज़रूरी है.

स्टैक के साइज़ की समस्याओं को रोकना

Delvik के पास नेटिव और Java कोड के लिए अलग-अलग स्टैक थे, जिनका डिफ़ॉल्ट Java था स्टैक का साइज़ 32 केबी और डिफ़ॉल्ट नेटिव स्टैक का साइज़ 1 एमबी होना चाहिए. ART में एक एकीकृत है बेहतर शहर के लिए स्टैक करें. आम तौर पर, ART Thread स्टैक साइज़ करीब-करीब Delvik के बराबर होना चाहिए. हालांकि, अगर आपने साफ़ तौर पर सेट करने के लिए, आपको स्टैक का साइज़ सेट करने की ज़रूरत पड़ सकती है. एआरटी.

  • Java में, साफ़ तौर पर स्टैक बनाए गए Thread कंस्ट्रक्टर को मिले कॉल की समीक्षा करें साइज़. उदाहरण के लिए, StackOverflowError होने पर आपको साइज़ बढ़ाना होगा.
  • C/C++ में, pthread_attr_setstack() और उन थ्रेड के लिए pthread_attr_setstacksize() जो इसके ज़रिए Java कोड भी चलाते हैं जेएनआई. जब कोई ऐप्लिकेशन JNI को कॉल करने की कोशिश करता है, तब लॉग की जाने वाली गड़बड़ी का एक उदाहरण यहां दिया गया है AttachCurrentThread() जब पीथ्रेड का साइज़ बहुत छोटा हो:
    F/art: art/runtime/thread.cc:435]
        Attempt to attach a thread with a too-small stack (16384 bytes)

ऑब्जेक्ट के मॉडल में बदलाव

Delvik ने गलत तरीके से सब-क्लास को पैकेज-प्राइवेट मेथड को बदलने की अनुमति दी. ART ऐसे मामलों में चेतावनी जारी करता है:

Before Android 4.1, method void com.foo.Bar.quux()
would have incorrectly overridden the package-private method in
com.quux.Quux

अगर आपको किसी दूसरे पैकेज में क्लास का तरीका बदलना है, तो तरीका public या protected है.

Object में अब निजी फ़ील्ड मौजूद हैं. फ़ील्ड पर दिखाई देने वाले ऐप्लिकेशन अपने क्लास के क्रम में उन्हें इस बात का ध्यान रखना चाहिए कि वे Object के फ़ील्ड. उदाहरण के लिए, अगर क्लास को दोहराना है क्रमिकता फ़्रेमवर्क के भाग के रूप में पदानुक्रम, तब रोकें जब

Class.getSuperclass() == java.lang.Object.class

का इस्तेमाल तब तक नहीं किया जा सकता, जब तक कि तरीका null वापस न कर दे.

अगर कोई सिग्नल नहीं होता है, तो अब प्रॉक्सी InvocationHandler.invoke() को null मिलता है के बजाय आर्ग्युमेंट के तौर पर लिखें. इस व्यवहार को पहले दस्तावेज़ में शामिल किया गया था, लेकिन सही तरीके से हैंडल नहीं किया गया है. Mockito के पिछले वर्शन में इसलिए, ART के साथ टेस्ट करते समय अपडेट किए गए Mockito वर्शन का इस्तेमाल करें.

एओटी को कंपाइल करने में आने वाली समस्याओं को ठीक करना

ART का Ahead-Of-Time (AOT) Java संकलन सभी मानक Java के साथ काम करना चाहिए कोड. कंपाइलेशन का काम ART's करता है dex2oat टूल; अगर आपको Google News से जुड़ी इंस्टॉल करते समय dex2oat, हमें बताएं (समस्याओं की रिपोर्ट करना देखें) ताकि हम उन्हें जल्दी से ठीक कर सकें किया जा सकता है. ध्यान देने वाली कुछ समस्याएं:

  • इंस्टॉल के समय, Delvik की तुलना में ART ज़्यादा बाइटकोड की पुष्टि करता है. Android बिल्ड टूल से बनाया गया कोड सही होना चाहिए. हालांकि, कुछ पोस्ट-प्रोसेसिंग टूल (खास तौर पर, ऐसे टूल जो अस्पष्ट बनाने के काम करते हैं) ऐसी अमान्य फ़ाइलें जिन्हें Delvik ने सहन किया हो, लेकिन ART ने अस्वीकार कर दिया हो. हमें ऐसी समस्याओं को खोजने और उन्हें ठीक करने के लिए टूल वेंडर के साथ मिलकर काम करना. कई मामलों में, टूल के नए वर्शन और DEX फ़ाइलों को फिर से जनरेट करने से, इन समस्याओं को ठीक किया जा सकता है समस्याएं.
  • एआरटी की पुष्टि करने वाले प्रोग्राम ने कुछ आम समस्याओं के बारे में बताया है. जैसे:
    • अमान्य कंट्रोल फ़्लो
    • असंतुलित monitorenter/monitorexit
    • पैरामीटर टाइप की सूची का साइज़, 0-लंबाई वाला है
  • कुछ ऐप्लिकेशन, इंस्टॉल की गई .odex फ़ाइल पर निर्भर होते हैं फ़ॉर्मैट को /system/framework, /data/dalvik-cache या DexClassLoader की ऑप्टिमाइज़ की गई आउटपुट डायरेक्ट्री में. ये फ़ाइलें अब ELF फ़ाइलें हो गई हैं न कि DEX फ़ाइलें. जब ART कोशिश करता है नामकरण और लॉक करने के नियमों का पालन करने के लिए, ऐप्लिकेशन को फ़ाइल फ़ॉर्मैट में होना चाहिए; फ़ॉर्मेट बिना किसी सूचना के बदला जा सकता है.

    ध्यान दें: Android 8.0 (एपीआई लेवल 26) में और उच्च, DexClassLoader ऑप्टिमाइज़ की गई आउटपुट डायरेक्ट्री को बंद कर दिया गया है. ज़्यादा जानकारी के लिए, DexClassLoader() अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है कंस्ट्रक्टर है.

समस्याओं को रिपोर्ट करना

अगर आपको कोई ऐसी समस्या आती है जो ऐप्लिकेशन जेएनआई की समस्याओं की वजह से नहीं है, तो रिपोर्ट करें https://code.google.com/p/android/issues/list पर जाकर उन्हें Android ओपन सोर्स प्रोजेक्ट समस्या ट्रैकर के ज़रिए सबमिट किया जा सकता है. Google में, "adb bugreport" और ऐप्लिकेशन का लिंक शामिल करें अगर Play Store उपलब्ध है, तो उसे भी डाउनलोड किया जा सकता है. अगर ऐसा नहीं किया जा सकता है, तो ऐसा APK अटैच करें जो समस्या. ध्यान दें कि समस्याएं (इसमें अटैचमेंट भी शामिल हैं) सार्वजनिक तौर पर मौजूद हैं दृश्य.