কীভাবে পরিচালনা করবেন: java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize () 10 সেকেন্ড ত্রুটির পরে সময়সীমা শেষ?


167

আমরা বেশ কয়েকটি সংখ্যক , এবং এর TimeoutExceptionsমধ্যে দেখতে পাচ্ছি । এর মধ্যে 90 +% Android 4.3 এ ঘটে 3 আমরা ক্ষেত্রের ব্যবহারকারীদের কাছ থেকে সমালোচনা থেকে এই প্রতিবেদন পাচ্ছি।GcWatcher.finalize, BinderProxy.finalizePlainSocketImpl.finalize

এখানে চিত্র বর্ণনা লিখুন

ত্রুটিটি এর বিভিন্নতা: " com.android.internal.BinderInternal$GcWatcher.finalize() timed out after 10 seconds"

java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
at java.lang.Thread.run(Thread.java:841)

এখনও অবধি আমরা বাড়িতে সমস্যাটি পুনরুত্পাদন করা বা এর কারণ কী হতে পারে তা নির্ধারণ করার কোনও ভাগ্য পাইনি।

কোন ধারণা কি এর কারণ হতে পারে? এটি কীভাবে ডিবাগ করবেন এবং অ্যাপের কোন অংশটি এটির কারণ ঘটবে তা খুঁজে বের করার কোনও ধারণা? যে কোনও বিষয় যা এই বিষয়ে আলোকপাত করে তা সহায়তা করে।

আরও স্ট্যাকট্রেস:

1   android.os.BinderProxy.destroy  
2   android.os.BinderProxy.finalize Binder.java, line 482
3   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
4   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
5   java.lang.Thread.run    Thread.java, line 841  

2

1   java.lang.Object.wait   
2   java.lang.Object.wait   Object.java, line 401
3   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 102
4   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 73
5   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
6   java.lang.Thread.run

3

1   java.util.HashMap.newKeyIterator    HashMap.java, line 907
2   java.util.HashMap$KeySet.iterator   HashMap.java, line 913
3   java.util.HashSet.iterator  HashSet.java, line 161
4   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 755
5   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 778
6   java.util.concurrent.ThreadPoolExecutor.shutdown    ThreadPoolExecutor.java, line 1357
7   java.util.concurrent.ThreadPoolExecutor.finalize    ThreadPoolExecutor.java, line 1443
8   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
9   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
10  java.lang.Thread.run

4

1   com.android.internal.os.BinderInternal$GcWatcher.finalize   BinderInternal.java, line 47
2   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
3   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
4   java.lang.Thread.run

2
কিছু মনে করবেন না, এটি bugzilla.mozilla.org/show_bug.cgi?id=864102 আমি নিশ্চিত করতে পারি যে আমাদের অ্যাপ্লিকেশনগুলি প্রভাবিত করছে, এটি গুগল প্লে পরিষেবাদির ইস্যুর মতো গন্ধ
পেয়েছে

ত্রুটিটি ফেলে দেওয়া কোডের লাইনটি সংস্করণ 4.3_r1 প্রবর্তন করা হয়েছিল, যা 5 জুন ২০১৩ সালে প্রকাশ হয়েছিল then তখন থেকেই সমস্যাটি ঘটতে পারে।
এডুব্রিগিনিটি

অ্যান্ড্রয়েড সংস্করণ ৪.২.২ এছাড়াও এই ব্যতিক্রম ছোঁড়া শুরু করেছিল তাই এটির কোনও গুগল প্লে আপডেট হতে পারে update
JWqvist

@ ইভেলিও তারাজোনা আমার কাছে এমন কিছু অ্যাপ্লিকেশন রয়েছে যা প্লে-পরিষেবাগুলি ব্যবহার করে না
লিগি

@ লিগি আপনার জন্য একই স্ট্যাক ট্রেস?
eveliotc

উত্তর:


220

সম্পূর্ণ প্রকাশ - আমি টিএলভি ড্রয়েডকনে পূর্বে উল্লিখিত আলোচনার লেখক।

আমি অনেকগুলি অ্যান্ড্রয়েড অ্যাপ্লিকেশন জুড়ে এই সমস্যাটি পরীক্ষা করার সুযোগ পেয়েছি এবং অন্যান্য বিকাশকারীরা যারা এটির মুখোমুখি হয়েছিল তাদের সাথে এটি নিয়ে আলোচনা করার সুযোগ পেয়েছিলাম - এবং আমরা সবাই একই পয়েন্টে পৌঁছেছি: এই সমস্যাটি এড়ানো যায় না, কেবলমাত্র হ্রাস করা যায় না।

এই ব্যতিক্রমটি কেন ছুঁড়ে দেওয়া হচ্ছে এবং কী কী সম্ভাব্য কারণ হতে পারে সে সম্পর্কে আরও ভালভাবে বুঝতে, আমি অ্যান্ড্রয়েড আবর্জনা সংগ্রহকারী কোডের ডিফল্ট বাস্তবায়নটি ঘনিষ্ঠভাবে দেখেছি। এমনকি আমি পরীক্ষার সময় একটি সম্ভাব্য মূল কারণও পেয়েছি।

সমস্যার মূলটি এই মুহুর্তে একটি ডিভাইস "ঘুমিয়ে যায়" কিছুক্ষণের জন্য - এর অর্থ ওএস বেশিরভাগ ইউজার ল্যান্ড প্রসেসগুলি কিছু সময়ের জন্য বন্ধ করে এবং স্ক্রিনটি বন্ধ করে সিপিইউ চক্র হ্রাস করে ব্যাটারি খরচ কম করার সিদ্ধান্ত নিয়েছে means , ইত্যাদি The যেভাবে এটি করা হয় - এটি লিনাক্স সিস্টেমের স্তরে যেখানে প্রক্রিয়াগুলি মাঝের রানকে থামানো হয়। এটি সাধারণ অ্যাপ্লিকেশন সম্পাদনের সময় যে কোনও সময় ঘটতে পারে, তবে এটি নেটিভ সিস্টেম কল এ বন্ধ হবে, কারণ প্রসঙ্গের স্যুইচিং কার্নেল স্তরে সম্পন্ন হয়েছে। সুতরাং - এখানেই ডালভিক জিসি গল্পটিতে যোগ দেয়।

ডালভিক জিসি কোড (যেমন এওএসপি সাইটে ডালভিক প্রকল্পে প্রয়োগ করা হয়েছে) কোডের জটিল টুকরো নয়। এটির কাজ করার প্রাথমিক উপায়টি আমার ড্রয়েডকন স্লাইডগুলিতে আচ্ছাদিত। আমি যা আচ্ছাদন করিনি তা হল বেসিক জিসি লুপ - সেই স্থানে যেখানে সংগ্রাহককে চূড়ান্ত করতে (এবং ধ্বংস) করার জন্য অবজেক্টগুলির একটি তালিকা রয়েছে। বেসটিতে লুপ যুক্তিটি এভাবে সহজ করা যায়:

  1. গ্রহণ করা starting_timestamp ,
  2. প্রকাশের জন্য অবজেক্টের তালিকার জন্য অবজেক্টটি সরান,
  3. রিলিজ অবজেক্ট - finalize()এবং কল করুন নেটিভdestroy() প্রয়োজনে ,
  4. গ্রহণ করা end_timestamp ,
  5. গণনা (end_timestamp - starting_timestamp ) এবং 10 সেকেন্ডের হার্ড কোডড সময়সীমার সাথে তুলনা করুন,
  6. সময়সীমা শেষ হয়ে গেলে - ফেলে দিন java.util.concurrent.TimeoutExceptionএবং প্রক্রিয়াটি মেরে ফেলুন।

এখন নিম্নলিখিত পরিস্থিতি বিবেচনা করুন:

অ্যাপ্লিকেশন তার কাজ করে চলমান।

এটি কোনও ব্যবহারকারীর মুখোমুখি নয়, এটি পটভূমিতে চলে।

এই ব্যাকগ্রাউন্ড অপারেশনের সময়, অবজেক্টগুলি তৈরি করা হয়, ব্যবহৃত হয় এবং মেমরি প্রকাশের জন্য সংগ্রহ করা দরকার।

অ্যাপ্লিকেশনটি একটি ওয়েকলকের সাথে বিরক্ত করে না - কারণ এটি ব্যাটারিকে বিরূপ প্রভাবিত করবে এবং অপ্রয়োজনীয় বলে মনে হচ্ছে।

এর অর্থ অ্যাপ্লিকেশনটি সময়ে সময়ে জিসিকে অনুরোধ করবে।

সাধারণত জিসির রানগুলি কোনও বাধা ছাড়াই সম্পন্ন হয়।

কখনও কখনও (খুব কমই) সিস্টেম জিসি রানের মাঝখানে ঘুমানোর সিদ্ধান্ত নেবে।

আপনি যদি আপনার অ্যাপ্লিকেশনটি যথেষ্ট পরিমাণ চালনা করেন এবং ডালভিক মেমরিটি নিবিড়ভাবে নিরীক্ষণ করেন তবে এটি ঘটবে।

এখন - বেসিক জিসি লুপের টাইমস্ট্যাম্প যুক্তি বিবেচনা করুন - ডিভাইসটির জন্য রান শুরু করা, নেওয়া start_stampএবং destroy()কোনও সিস্টেম অবজেক্টের নেটিভ কলটিতে ঘুমাতে যাওয়া সম্ভব ।

এটি যখন জেগে ওঠে এবং পুনরায় সঞ্চালন শুরু করে, শেষটি destroy()শেষ হয়ে যায় এবং পরের end_stampবারটি সময় নেয়destroy() কল + ঘুমের সময় হয়।

যদি ঘুমের সময় দীর্ঘ হয় (10 সেকেন্ডের বেশি), তবে java.util.concurrent.TimeoutExceptionনিক্ষেপ করা হবে।

আমি এটিকে বিশ্লেষণ অজগর স্ক্রিপ্ট থেকে উত্পন্ন গ্রাফগুলিতে দেখেছি - অ্যান্ড্রয়েড সিস্টেম অ্যাপ্লিকেশনগুলির জন্য, কেবল আমার নিজের পর্যবেক্ষণকৃত অ্যাপস নয়।

পর্যাপ্ত লগ সংগ্রহ করুন এবং আপনি শেষ পর্যন্ত এটি দেখতে পাবেন।

শেষের সারি:

সমস্যাটি এড়ানো যায় না - আপনার অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে চললে আপনি এটির মুখোমুখি হবেন।

আপনি একটি ওয়েকলক গ্রহণ করে ডিভাইসটিকে ঘুমানোর হাত থেকে রক্ষা করতে পারেন, তবে এটি সম্পূর্ণ আলাদা গল্প, এবং একটি নতুন মাথা ব্যাথা এবং সম্ভবত অন্য কোনও কনটে অন্য কথা।

আপনি জিসি কল হ্রাস করে সমস্যাটি হ্রাস করতে পারেন - দৃশ্যের কম সম্ভাবনা তৈরি করে (টিপস স্লাইডগুলিতে রয়েছে)।

আমার এখনও ডালভিক 2 (ওরফে এআরটি) জিসি কোড - যা একটি নতুন জেনারেশনাল কমপ্যাক্টিং বৈশিষ্ট্য নিয়ে গর্ব করে, বা অ্যান্ড্রয়েড ললিপপে কোনও পরীক্ষা-নিরীক্ষা করার সুযোগ পেল না।

7/5/2015 যোগ হয়েছে:

এই ক্র্যাশ ধরণের জন্য ক্র্যাশ প্রতিবেদন সমষ্টি পর্যালোচনা করার পরে, দেখে মনে হচ্ছে অ্যান্ড্রয়েড ওএসের 5.0+ সংস্করণ (এআরটি সহ ললিপপ) থেকে এই ক্র্যাশগুলির মধ্যে এই ক্র্যাশ প্রকারের 0.5% ভাগ রয়েছে। এর অর্থ হ'ল এআরটি জিসি পরিবর্তনগুলি এই ক্র্যাশের ফ্রিকোয়েন্সি হ্রাস করেছে।

6/1/2016 যোগ হয়েছে:

দেখে মনে হচ্ছে অ্যান্ড্রয়েড প্রকল্পটি ডালভিক ২.০ (ওরফে এআরটি) তে কীভাবে জিসি কাজ করে সে সম্পর্কে অনেক তথ্য যুক্ত করেছে।

আপনি এটি সম্পর্কে এখানে পড়তে পারেন - ডিআবাগিং এআরটি আবর্জনা সংগ্রহ

এটি আপনার অ্যাপ্লিকেশনটির জন্য জিসি আচরণ সম্পর্কে তথ্য পাওয়ার জন্য কয়েকটি সরঞ্জাম নিয়েও আলোচনা করে।

আপনার অ্যাপ্লিকেশন প্রসেসে একটি সাইনকিউটি প্রেরণ করা মূলত একটি এএনআর তৈরি করবে এবং বিশ্লেষণের জন্য অ্যাপ্লিকেশন স্থিতিকে একটি লগ ফাইলে ফেলে দেবে।


আমার ক্ষেত্রে, আমি পটভূমিতে যে কোড / সময় চালাচ্ছি তার পরিমাণ হ্রাস করার উপায়গুলি খুঁজে বের করে এটি হ্রাস করার চেষ্টা করার পরিকল্পনা করছি। বিষয়টিতে আপনার গবেষণার জন্য ধন্যবাদ।
parkerfath

আপনার অ্যাপ্লিকেশনটিতে যে কোনও ব্যাকগ্রাউন্ড প্রসেসিং অপসারণ করা সমস্যা কমাতে ব্যাপক সাহায্য করবে।
ওবা

এটি মূল্যবান জন্য, এটি মার্শমেলোতে এখনও ঘটে (6.0.1)। এটি বলেছিল, আমি এই ত্রুটিটি কেবল একবারই পেয়েছি। সুতরাং এটি একটি বিশাল সমস্যা বলে মনে হয় না। আপনার পুরো ব্যাখ্যা জন্য আপনাকে ধন্যবাদ।
ন্নোসোস

কিছু সময়ের পরে, আমি স্বতন্ত্র ধারণা পেয়েছিলাম যে ওএসে এই সমস্যাটি ঠিক করা খুব সমস্যাযুক্ত, এবং গুগল এবং ইএম এর মধ্যে সহযোগিতা প্রয়োজন। আমি শীঘ্রই এটি যে কোনও সময় স্থির হবে আশা করি না।
ওবা

আমি জাগ্রত ব্যবহার করছি তবে অ্যান্ড্রয়েড ৪.৪.২ এ এখনও এই সমস্যার মুখোমুখি হয়েছি। আমার অ্যাপ্লিকেশনটিতে কিছু ব্যাকগ্রাউন্ড অপারেশন রয়েছে তবে চার্জ কেবলটি মাউন্ট করার সময় পুরো দিন ধরে কাজ করার জন্য ডিজাইন করা হয়। এই সমস্যাটি প্রশমিত করার কোনও আলাদা উপায় আছে কি?
অরকুন সেভসে

74

ক্র্যাশলাইটিক্স ব্যবহার করে আমরা আমাদের অ্যাপ্লিকেশন ধরে ক্রমাগত এটি দেখতে পাই। প্ল্যাটফর্ম কোডে সাধারণত ক্র্যাশ ঘটে। একটি ছোট নমুনা:

android.datedia.CursorWindow.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

java.util.regex.Matcher.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

android.ographicics.Bitmap it বিটম্যাপ ফিনালাইজার.ফাইনালাইজ () 10 সেকেন্ড পরে সময়সীমা শেষ

org.apache.http.impl.conn.SingleClientConnManager.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

java.util.concurrent.ThreadPoolExecutor.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

android.os.BinderProxy.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

android.ographicics.Path.finalize () 10 সেকেন্ড পরে সময়সীমা শেষ

যে ডিভাইসগুলিতে এটি ঘটে সেগুলি স্যামসুং দ্বারা উত্পাদিত ডিভাইসগুলি অত্যধিকভাবে (তবে একচেটিয়াভাবে নয়) devices এর অর্থ হ'ল আমাদের বেশিরভাগ ব্যবহারকারী স্যামসাং ডিভাইস ব্যবহার করছেন; পর্যায়ক্রমে এটি স্যামসাং ডিভাইসগুলির সাথে সমস্যা চিহ্নিত করতে পারে। আমি সত্যিই নিশ্চিত নই।

আমি মনে করি এটি সত্যিই আপনার প্রশ্নের উত্তর দেয় না, তবে আমি কেবল আরও জোর দিয়ে বলতে চেয়েছি যে এটি বেশ সাধারণ বলে মনে হচ্ছে এবং এটি আপনার আবেদনের সাথে সুনির্দিষ্ট নয়।


16
এটি অ্যান্ড্রয়েড 5.0.1 সংস্করণেও ঘটছে এবং এটি স্যামসাং ডিভাইসে সীমাবদ্ধ বলে মনে হয় না। এটি নেক্সাস on. এ ঘটেছিল
শোভিত পুরী 15'15

4
XiaOMI

কেবলমাত্র আমরা চাইছিলাম যে আমরা স্যামসং ট্যাবলেটগুলিতে এই ক্র্যাশগুলির সিংহভাগ দেখতে পাচ্ছি। কীভাবে ট্যাবলেটগুলি ব্যাকগ্রাউন্ডে থাকা অ্যাপ্লিকেশনগুলি পরিচালনা করে সেগুলির সাথে সামসং কী আলাদাভাবে কাজ করেছে তা নিশ্চিত নয়।
বন্ধুত্বপূর্ণ

1
অ্যান্ড্রয়েড ৪.৪.৪ এ আমার সমস্যা আছে। HUAWEI দ্বারা নির্মিত ডিভাইস।
রমেশবাবু

1
যদি আমি অ্যান্ড্রয়েড 5.0.2 স্যামসং ডিভাইসে লিক ক্যানারি লাইব্রেরি ব্যবহার করি তবে আমার অ্যাপ্লিকেশানটি ক্র্যাশ হয়ে গেছে। আমি যদি লাইব্রেরির সূচনাটি অক্ষম করি তবে অ্যাপটি ঠিকঠাক কাজ করে।
ভ্যানোমার্ট

15

আমি এই সমস্যাটি সম্পর্কে কিছু স্লাইড পেয়েছি।

http://de.slideshare.net/DroidConTLV/android-crash-analysis-and-the-dalvik-garbage-collector-tools-and-tips

এই স্লাইডগুলিতে লেখক জানিয়েছেন যে প্রচুর পরিমাণে বস্তু বা বিশাল বস্তু যদি গাদা হয়ে থাকে তবে এটি জিসির সমস্যা বলে মনে হচ্ছে। স্লাইডটিতে এই সমস্যাটি বিশ্লেষণের জন্য একটি নমুনা অ্যাপ্লিকেশন এবং একটি পাইথন স্ক্রিপ্টের একটি রেফারেন্স অন্তর্ভুক্ত রয়েছে।

https://github.com/oba2cat3/GCTest

https://github.com/oba2cat3/logcat2memorygraph

তদুপরি আমি এই দিকে # 3 মন্তব্যে একটি ইঙ্গিত পেয়েছি: https://code.google.com/p/android/issues/detail?id=53418#c3


7

আমরা থামিয়ে সমস্যার সমাধান করেছি FinalizerWatchdogDaemon

public static void fix() {
    try {
        Class clazz = Class.forName("java.lang.Daemons$FinalizerWatchdogDaemon");

        Method method = clazz.getSuperclass().getDeclaredMethod("stop");
        method.setAccessible(true);

        Field field = clazz.getDeclaredField("INSTANCE");
        field.setAccessible(true);

        method.invoke(field.get(null));

    }
    catch (Throwable e) {
        e.printStackTrace();
    }
}

আপনি অ্যাপ্লিকেশনটির জীবনচক্রটিতে পদ্ধতিটি কল করতে পারেন, পছন্দ করুন attachBaseContext()। একই কারণে, আপনি সমস্যার সমাধান করতে ফোনের উত্পাদন নির্দিষ্ট করতে পারেন, এটি আপনার উপর নির্ভর করে।


আমাদের জন্য কাজ করে না, আমি বুঝতে পারি না কেন। কোড ব্যতিক্রম ছাড়াই সম্পূর্ণ করে তবে আমরা ক্র্যাশলাইটিক্স প্রতিবেদন এবং গুগল প্লে কনসোলগুলিতে এখনও সেগুলি পেয়েছি।
আন্তন ব্রেসোভ

5

10 সেকেন্ড পরে ব্রডকাস্ট রিসিভারের সময়সীমা শেষ। সম্ভবত আপনি কোনও সম্প্রচারের রিসিভারের একটি অ্যাসিঙ্ক্রোনাস কল (ভুল) করছেন এবং 4.3 আসলে এটি সনাক্ত করে c


3
এটি সনাক্ত করা এবং এটি সম্পর্কে আপনাকে যথেষ্ট পরিমাণে না বলার জন্য অকেজো মনে হচ্ছে less আমাদের কোন সম্প্রচারটি ভাল লাগবে তা জানান।
অ্যারন টি হ্যারিস

আমি ভুল হলে ক্ষমা করে দিই, তবে আমি মনে করি না যে সম্প্রচারের রিসিভারের সময়সীমা এই বিশেষ ক্রাশের কারণ। দশকের সীমা এড়াতে ভাল অনুশীলন, তবে এটির দাবিদারের চেয়ে আলাদা সমস্যা।
parkerfath

আমার মস্তিষ্কে মাত্র 10 সেকেন্ড রয়েছে। ডেভেলপার.অ্যান্ড্রয়েড / ট্রেনিং / আর্টিকেলস / সুপারফ-anr.html আইডিকে যদি এটি ক্রাশের কারণ হয়ে থাকে।
danny117

আপনার বক্তব্য দৃ solid় এবং একটি ভাল অনুশীলন। তবে, ডিভাইসের একটি নির্দিষ্ট সেট সম্পর্কে মূল পোস্টারটিতে একটি নির্দিষ্ট প্রশ্ন রয়েছে। আমি এই পোস্টের অন্যান্য দর্শকদের পরামর্শ দিচ্ছি যদি তারা একই লক্ষণগুলি দেখতে পাচ্ছে তবে ক্রিস্টোফরের উত্তর এবং ওবার উত্তর যাচাই করার জন্য পরামর্শ দেবে (স্যামসাং ডিভাইসগুলি (
উদাহরণস্বরূপ

আমি এখানে ব্যাশ ডিভাইস প্রস্তুত করি না এটি শর্তগুলির বিরুদ্ধে হবে।
danny117

5

এই সমস্যাটি সমাধানের জন্য এখানে দিদির একটি কার্যকর সমাধান রয়েছে, যেহেতু এই বাগটি খুব সাধারণ এবং কারণটি খুঁজে পাওয়া শক্ত, তাই এটি সিস্টেম সমস্যার মতো দেখা যায়, কেন আমরা এটি সরাসরি উপেক্ষা করতে পারি না course অবশ্যই আমরা এটিকে অবহেলা করতে পারি, এখানে নমুনা কোড:

final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = 
        Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        if (t.getName().equals("FinalizerWatchdogDaemon") && e instanceof TimeoutException) {
        } else {
            defaultUncaughtExceptionHandler.uncaughtException(t, e);
        }
    }
});

একটি বিশেষ ডিফল্ট অনাবৃত ব্যতিক্রম হ্যান্ডলার সেট করে অ্যাপ্লিকেশন সেই থ্রেডগুলির জন্য অপ্রয়োজনীয় ব্যতিক্রমগুলি পরিচালিত করার পদ্ধতিটিকে পরিবর্তন করতে পারে যা সিস্টেমের দেওয়া যে কোনও ডিফল্ট আচরণ ইতিমধ্যে গ্রহণ করবে। যখন TimeoutExceptionএকটি থ্রেড নামের থ্রেড থেকে ফেলে দেওয়া হয়FinalizerWatchdogDaemon , তখন এই বিশেষ হ্যান্ডলার হ্যান্ডলার চেইনটি ব্লক করে দেবে, সিস্টেম হ্যান্ডলারটি কল করা হবে না, তাই ক্রাশ এড়ানো হবে।

অনুশীলনের মাধ্যমে, অন্য কোনও খারাপ প্রভাব পাওয়া যায় নি। জিসি সিস্টেম এখনও কাজ করছে, সিপিইউ ব্যবহার হ্রাস হওয়ার সাথে সাথে টাইমআউটগুলি হ্রাস করা হবে।

আরও তথ্যের জন্য দেখুন: https://mp.weixin.qq.com/s/uFcFYO2GtWWiblotem2bGg


4

একটি বিষয় যা সত্যই সত্য সত্য তা হ'ল এই সময়ে ডিভাইসটি কিছু মেমরির জন্য দম বন্ধ করে দিবে (যা সাধারণত জিসির সম্ভবত ট্রিগার হওয়ার কারণ হয়ে থাকে)।

আগে প্রায় সমস্ত লেখক দ্বারা উল্লিখিত হিসাবে, অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে থাকা অবস্থায় অ্যান্ড্রয়েড যখন জিসি চালানোর চেষ্টা করে তখন এই সমস্যাটি তত্পর হয়। বেশিরভাগ ক্ষেত্রে যেখানে আমরা এটি পর্যবেক্ষণ করেছি, ব্যবহারকারী তাদের স্ক্রীনটি লক করে অ্যাপটিকে বিরতি দিয়েছেন। এটি অ্যাপ্লিকেশনের কোথাও মেমরি ফাঁস বা ডিভাইসটি ইতিমধ্যে খুব বেশি লোড হওয়া ইঙ্গিত দিতে পারে। সুতরাং এটি হ্রাস করার একমাত্র বৈধ উপায় হ'ল:

  • কোনও মেমরি ফাঁস নেই তা নিশ্চিত করার জন্য, এবং
  • সাধারণভাবে অ্যাপটির মেমরির পদচিহ্ন হ্রাস করতে।

1
try {
    Class<?> c = Class.forName("java.lang.Daemons");
    Field maxField = c.getDeclaredField("MAX_FINALIZE_NANOS");
    maxField.setAccessible(true);
    maxField.set(null, Long.MAX_VALUE);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}

ঘুমের সময়কাল> 100 সেকেন্ড হলে এটি সমস্যার সমাধান করবে না। কেন এটি ম্যাক্সপেক্টে সেট করবেন না?
ওবা

হ্যাঁ, আমি কেবল উদাহরণ দিচ্ছি ~
কোট 32

1
অবিচ্ছিন্ন ইনলাইনিংয়ের কারণে এটি কাজ করা উচিত নয়। ক্ষেত্রের মান পরিবর্তন করা কলকারীদের ইনলাইন করা মানকে প্রভাবিত করবে না।
hqzxzwb

0

চূড়ান্তকরণের কিউইউটি খুব দীর্ঘ

আমি মনে করি যে জাভাতে ব্যবহারকারীকে চূড়ান্তভাবে চূড়ান্তভাবে চূড়ান্ত দৈর্ঘ্য হ্রাস করতে GC.SuppressFinalize () এবং GC.ReRegisterForFinalize () প্রয়োজন হতে পারে

যদি জেভিএম 'সোর্স কোড উপলভ্য থাকে তবে অ্যান্ড্রয়েড রম প্রস্তুতকারকের মতো এই পদ্ধতিগুলি স্বয়ংক্রিয়ভাবে প্রয়োগ করতে পারে


0

এটি একটি অ্যান্ড্রয়েড রানটাইম বাগের মতো মনে হচ্ছে। সেখানে চূড়ান্তরূপে উপস্থিত রয়েছে যা তার পৃথক থ্রেডে চলছে এবং স্ট্যাকট্রেসের বর্তমান ফ্রেমে না থাকলে বস্তুগুলিতে চূড়ান্ত () পদ্ধতি কল করে। উদাহরণস্বরূপ নিম্নলিখিত কোডগুলি (এই সমস্যাটি যাচাই করার জন্য তৈরি করা হয়েছে) ক্রাশের সাথে শেষ হয়েছে।

আসুন কিছু কার্সার আসুন যা চূড়ান্তকরণ পদ্ধতিতে কিছু করে (যেমন SqlCipher বেশী, বন্ধ করুন) (যা বর্তমানে ব্যবহৃত ডেটাবেসে লক করে)

private static class MyCur extends MatrixCursor {


    public MyCur(String[] columnNames) {
        super(columnNames);
    }

    @Override
    protected void finalize() {
        super.finalize();

        try {
            for (int i = 0; i < 1000; i++)
                Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

এবং আমরা কিছু দীর্ঘ চলমান জিনিসগুলি কার্সার খোলার মাধ্যমে করি:

for (int i = 0; i < 7; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                MyCur cur = null;
                try {
                    cur = new MyCur(new String[]{});
                    longRun();
                } finally {
                    cur.close();
                }
            }

            private void longRun() {
                try {
                    for (int i = 0; i < 1000; i++)
                        Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

এটি নিম্নলিখিত ত্রুটির কারণ:

FATAL EXCEPTION: FinalizerWatchdogDaemon
                                                                        Process: la.la.land, PID: 29206
                                                                        java.util.concurrent.TimeoutException: MyCur.finalize() timed out after 10 seconds
                                                                            at java.lang.Thread.sleep(Native Method)
                                                                            at java.lang.Thread.sleep(Thread.java:371)
                                                                            at java.lang.Thread.sleep(Thread.java:313)
                                                                            at MyCur.finalize(MessageList.java:1791)
                                                                            at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
                                                                            at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
                                                                            at java.lang.Thread.run(Thread.java:762)

স্কেলসিফারের সাথে উত্পাদনের বৈকল্পিকটি খুব সাদৃশ্য:

12-21 15:40:31.668: E/EH(32131): android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): java.util.concurrent.TimeoutException: android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Object.wait(Native Method)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.parkFor$(Thread.java:2128)
12-21 15:40:31.668: E/EH(32131): 	at sun.misc.Unsafe.park(Unsafe.java:325)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:840)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:873)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:200)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteDatabase.lock(SourceFile:518)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteProgram.close(SourceFile:294)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteQuery.close(SourceFile:136)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteCursor.close(SourceFile:510)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:2746)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.finalize(ContentResolver.java:2757)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.run(Thread.java:762)

পুনঃসূচনা: ASAP বন্ধ কর্সারগুলি বন্ধ করুন। কমপক্ষে অ্যান্ড্রয়েড 7 সহ স্যামসাং এস 8 এ যেখানে সমস্যাটি দেখা গেছে।


0

আপনার তৈরি করা ক্লাসগুলির জন্য (যেমন অ্যান্ড্রয়েডের অংশ নয়) ক্র্যাশ সম্পূর্ণরূপে এড়ানো সম্ভব।

যে কোনও শ্রেণি প্রয়োগ finalize()করে যা @ ওবা দ্বারা ব্যাখ্যা অনুসারে ক্রাশ হওয়ার কিছু অপ্রয়োজনীয় সম্ভাবনা থাকে। সুতরাং ক্লিনআপ সঞ্চালনের জন্য ফাইনালাইজার ব্যবহার করার পরিবর্তে, এ ব্যবহার করুনPhantomReferenceQueue

উদাহরণস্বরূপ প্রতিক্রিয়া নেটিভের বাস্তবায়নটি দেখুন: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.