2011-12-14 5 views
9

मैं अब डेलविक वीएम के कचरा कलेक्टर की वास्तुकला का वर्णन करने वाले विस्तृत डिजाइन दस्तावेजों के लिए कुछ समय ढूंढ रहा हूं, लेकिन बहुत कुछ नहीं हुआ है। जीसी रनों के प्रदर्शन के प्रभाव को देखते हुए मैं वास्तव में 5 विशिष्ट मुद्दों की बेहतर समझ लेना चाहता हूं: 1. एंड्रॉइड में जीसी वास्तव में क्या ट्रिगर करता है? अन्य वीएम कार्यान्वयन मैंने देखा है कि आमतौर पर उनके जीसी को चलाने के लिए सिग्नल प्राप्त होने से पहले सिस्टम मेमोरी के एक निश्चित प्रतिशत को आवंटित किया जा सकता है। स्कैनिंग निम्नलिखित LogCat तथापि Dalvik जीसी काफी often-- भाग में कम से कम चल रहा है दिखाने के लिए लगता हैएंड्रॉइड जीसी विचार- जीसी कब चलती है, और क्या इसके रन स्टेट को कोड से ट्रैक किया जा सकता है?

12-14 11:34:57.753: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 735 objects/54272 bytes 
in 90ms 
12-14 11:34:57.893: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 256 objects/12240 bytes 
in 61ms 
12-14 11:34:57.943: I/jPCT-AE(279): Loading Texture... 
12-14 11:34:57.993: D/dalvikvm(279): GC_FOR_MALLOC freed 65 objects/2840 bytes in 
52ms 
12-14 11:34:58.013: I/dalvikvm-heap(279): Grow heap (frag case) to 5.039MB for 
1048592-byte allocation 
12-14 11:34:58.073: D/dalvikvm(279): GC_FOR_MALLOC freed 1 objects/40 bytes in 59ms 
12-14 11:34:58.243: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 11 objects/432 bytes in 
55ms 
12-14 11:34:58.283: I/jPCT-AE(279): Loading Texture... 
12-14 11:34:58.333: D/dalvikvm(279): GC_FOR_MALLOC freed 10 objects/416 bytes in 46ms 
12-14 11:34:58.344: I/dalvikvm-heap(279): Grow heap (frag case) to 6.040MB for 
1048592-byte allocation 
12-14 11:34:58.423: D/dalvikvm(279): GC_FOR_MALLOC freed 2 objects/80 bytes in 75ms 
12-14 11:34:58.563: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 10 objects/384 bytes in 
47ms 
12-14 11:34:58.603: I/jPCT-AE(279): Loading Texture... 
12-14 11:34:58.653: D/dalvikvm(279): GC_FOR_MALLOC freed 11 objects/464 bytes in 44ms 
12-14 11:34:58.663: I/dalvikvm-heap(279): Grow heap (frag case) to 7.040MB for 
1048592-byte allocation 
12-14 11:34:58.743: D/dalvikvm(279): GC_FOR_MALLOC freed 2 objects/80 bytes in 75ms 
12-14 11:34:58.973: I/System.out(279): started document! 
... 
12-14 11:43:05.393: I/jPCT-AE(279): Memory usage before compacting: 5867 KB used out 
of 6215 KB 
12-14 11:43:05.453: D/dalvikvm(279): GC_EXPLICIT freed 2560 objects/145712 bytes in 
61ms 
12-14 11:43:05.503: D/dalvikvm(279): GC_EXPLICIT freed 295 objects/21448 bytes in 
51ms 
12-14 11:43:05.717: I/jPCT-AE(279): Memory usage after compacting: 5705 KB used out of 
6215 KB 
... 
12-14 11:43:05.792: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 105 objects/6152 bytes 
in 56ms 
12-14 11:43:05.855: D/dalvikvm(279): GC_FOR_MALLOC freed 3 objects/80 bytes in 51ms 
... 
12-14 11:43:12.863: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 864 objects/1099072 
bytes in 70ms 
12-14 11:43:13.053: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 45 objects/1760 bytes 
in 55ms 
12-14 11:43:14.533: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 49 objects/2376 bytes 
in 58ms 
12-14 11:43:14.933: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 34 objects/1408 bytes 
in 55ms 
12-14 11:43:15.423: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 13 objects/504 bytes in 
58ms 
12-14 11:43:15.953: D/dalvikvm(279): GC_EXTERNAL_ALLOC freed 13 objects/520 bytes in 
56ms 
... 
12-14 11:43:31.203: I/jPCT-AE(279): Visibility lists disposed! 
12-14 11:43:31.203: I/jPCT-AE(279): All texture data unloaded from gpu! 
12-14 11:43:31.203: I/jPCT-AE(279): Renderer disposed! 
12-14 11:43:31.203: I/jPCT-AE(279): Static references cleared... 
... 
12-14 11:43:36.943: E/dalvikvm-heap(279): 2964320-byte external allocation too large 
for this process. 
12-14 11:43:36.953: E/GraphicsJNI(279): VM won't let us allocate 2964320 bytes 
12-14 11:43:36.953: D/AndroidRuntime(279): Shutting down VM 
12-14 11:43:36.953: W/dalvikvm(279): threadid=1: thread exiting with uncaught 
exception (group=0x4001d800) 
12-14 11:43:36.973: E/AndroidRuntime(279): FATAL EXCEPTION: main 
12-14 11:43:36.973: E/AndroidRuntime(279): android.view.InflateException: Binary XML 
file line #33: Error inflating class <unknown> 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.createView(LayoutInflater.java:513) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
com.android.internal.policy.impl.PhoneLayoutInflater. 
onCreateView(PhoneLayoutInflater.java:56) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.rInflate(LayoutInflater.java:618) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.rInflate(LayoutInflater.java:621) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.inflate(LayoutInflater.java:407) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.inflate(LayoutInflater.java:320) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
com.ai.ultimap.views.Manual.onItemClick(Manual.java:467) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.widget.AdapterView.performItemClick(AdapterView.java:284) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.widget.AbsListView$PerformClick.run(AbsListView.java:1696) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.os.Handler.handleCallback(Handler.java:587) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.os.Handler.dispatchMessage(Handler.java:92) 
12-14 11:43:36.973: E/AndroidRuntime(279): at android.os.Looper.loop(Looper.java:123) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.app.ActivityThread.main(ActivityThread.java:4627) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
java.lang.reflect.Method.invokeNative(Native Method) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
java.lang.reflect.Method.invoke(Method.java:521) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
12-14 11:43:36.973: E/AndroidRuntime(279): at dalvik.system.NativeStart.main(Native 
Method) 
12-14 11:43:36.973: E/AndroidRuntime(279): Caused by: 
java.lang.reflect.InvocationTargetException 
12-14 11:43:36.973: E/AndroidRuntime(279): at android.widget.ImageView.<init> 
(ImageView.java:108) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
java.lang.reflect.Constructor.constructNative(Native Method) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
java.lang.reflect.Constructor.newInstance(Constructor.java:446) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.view.LayoutInflater.createView(LayoutInflater.java:500) 
12-14 11:43:36.973: E/AndroidRuntime(279): ... 18 more 
12-14 11:43:36.973: E/AndroidRuntime(279): Caused by: java.lang.OutOfMemoryError: 
bitmap size exceeds VM budget 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.Bitmap.nativeCreate(Native Method) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.Bitmap.createBitmap(Bitmap.java:468) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.Bitmap.createBitmap(Bitmap.java:435) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.Bitmap.createScaledBitmap(Bitmap.java:340) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:488) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:462) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.content.res.Resources.loadDrawable(Resources.java:1709) 
12-14 11:43:36.973: E/AndroidRuntime(279): at 
android.content.res.TypedArray.getDrawable(TypedArray.java:601) 
12-14 11:43:36.973: E/AndroidRuntime(279): at android.widget.ImageView.<init> 
(ImageView.java:118) 
12-14 11:43:36.973: E/AndroidRuntime(279): ... 22 more 
12-14 11:43:38.763: I/Process(279): Sending signal. PID: 279 SIG: 9 

आप मैं विशेष रूप से एक ~ 3 एमबी बिटमैप लोड होने के दौरान एक OutOfMemory त्रुटि में चल रहा हूँ देख सकते हैं ... यह जीसी हाल ही में भागने के बाद से मुझे समझ में नहीं आता है और आवंटित कुछ भी नहीं है क्योंकि वीएम को 3 एमबी क्षमता (256 एमबी) के भीतर लाया जाना चाहिए था। क्या उस 256 एमबी सिस्टम रैम का केवल एक छोटा प्रतिशत है जो वास्तव में वीएम को दुर्घटनाग्रस्त होने से पहले दिया जाता है? क्या यह हो सकता है कि बिटमैप लोडिंग प्रक्रिया की अपनी याददाश्त आवंटन कैप हो? मुझे पता है कि ऑब्जेक्ट पूलिंग गेम लूप के दौरान जीसी से बचने का प्रयास करने का एक अच्छा तरीका है, लेकिन बिना किसी जानबूझकर डेलविक जीसी को ट्रिगर करता है, हम अभी भी ओएस में भरोसेमंद भरोसा रखते हैं और प्रदर्शन के सर्वोत्तम कार्यक्रमों की Google की अस्पष्ट चर्चाएं कर रहे हैं।

  1. कर सकते हैं जीसी राज्य कोड से नज़र रखी जा ताकि बड़े संसाधन आवंटन रणनीतिक भर में उपलब्ध की योजना बनाई जा सकता है (उदाहरण के लिए, 'चल', 'चलना समाप्त' 'चलाने के बारे में') याद? मैंने इस पोस्ट को इस मामले पर पढ़ा है: Determine when the Android GC runs जो एक दिलचस्प संभावित समाधान प्रदान करता है, लेकिन फिर भी 'चाल' पर निर्भर करता है। मैं जानना चाहता हूं कि एक समर्थित एपीआई कॉल कहीं है जहां कचरा कलेक्टर की सटीक स्थिति को ट्रैक करने के लिए उत्पादन कोड (केवल डीबग नहीं) पर भरोसा किया जा सकता है। System.gc() कुछ मामलों में उपयोगी हो सकता है अगर जीसी राज्य की जांच की जा सकती है; अन्यथा, चूंकि यह तत्काल जीसी चलाने का वादा नहीं कर सकता है, इसकी उपयोगिता काफी कम हो जाती है।

  2. क्या जीसी हमेशा सिस्टम-व्यापी है, या जीसी के कारण संभावित प्रदर्शन अंतराल मुद्दों से बचने के लिए धागे को अलग कर सकता है (जैसे एक गेम के लिए समर्पित प्रतिपादन धागा)?

  3. निम्नलिखित काल्पनिक परिदृश्य को देखते हुए: 'मैंने किसी चीज़ जो लागत (वीएम रैम बजट)/2 बाइट्स का दृष्टांत के लिए है, और मैं इसे तुरंत का दृष्टांत एक भी संदर्भ के साथ। मैं उस संदर्भ को रद्द कर देता हूं, वस्तु को जीसी के लिए योग्य बना देता हूं लेकिन निश्चित रूप से वास्तव में इसकी याददाश्त को अभी तक जारी नहीं करता हूं। मैं तुरंत ऑब्जेक्ट को तुरंत चालू करता हूं। ' क्या यह वीएम को दुर्घटनाग्रस्त करेगा या क्या वीएम को दुर्घटनाग्रस्त होने से बचने के लिए ओएस ऐसी चरम परिस्थितियों को स्वचालित रूप से संभालता है? यदि ओएस इसे संभाल नहीं पाता है, तो मैं इसे एक अच्छा उदाहरण के रूप में उद्धृत करूंगा कि मेरा प्रश्न # 2 ऊपर क्यों वैध है; यदि जीसी राज्य को ट्रैक किया जा सकता है, तो विशाल ऑब्जेक्ट आवंटन मुद्दों को संभालने के लिए स्रोत में तर्क शामिल किया जा सकता है (वास्तव में बुरी तरह से डिज़ाइन किए गए वर्गों की तुलना में बड़े संसाधन होने की अधिक संभावना है) यह देखने के लिए कि जीसी योग्य वस्तु से स्मृति को लोड करने से पहले मुक्त किया गया था या नहीं पृष्ठभूमि में जीसी मतदान करते समय नया विशाल ऑब्जेक्ट उदाहरण, और एक छोटी लोडिंग एनीमेशन दिखा रहा है। यह अनुप्रयोग से बचने के लिए त्रुटियों का जवाब नहीं दे सकता है और साथ ही स्मृति त्रुटियों से वैध ... कुछ प्रकार का ऑनजीसी() श्रोता आदर्श होगा; क्या एक जीसी श्रोता ओएस कर्नेल को फिर से निर्मित किए बिना देशी कोड में कार्यान्वित किया जा सकता है?

5. अंत में, कुछ स्रोत कोड ... क्या मेरे पास प्रदर्शन-कुशल एंड्रॉइड प्रोग्रामिंग का सही विचार है?

गतिविधि वर्ग:

package com.ai.ultimap; 

//imports omitted... 

public class UltiMapActivity extends Activity { 
//Housekeeping 
private String viewDriverID = ""; 
private static final int TUTORIAL = 7; 

//visuals 
private HomeView hv; //home view 
private ConfigView cv; //config view 
private MapView mv; //map view 
private Manual man; //manual view 
private int manCount = 0; //tracks the number of times the manual has been called 
    //with menu button, ignoring button presses unless value is zero 
private PathCreator pcv; //path creator view 
private MasterGL mgl; //the gl center 
private String pending = "Coming soon..."; 
private PathCreator draw; 
private Surfacer morlock; 
// Used to handle pause and resume... 
private static UltiMapActivity master; 

//XML I/O considerations 
private String fXML = "mypaths.xml"; 
private String sXML = "data was not saved properly...?"; 
private FileOutputStream fos; 
private FileInputStream fis; 
private FileWriter fw; 
private FileReader fr; 
private Date theDate = new Date(); 
private char[] buf = new char[1]; 

//Feedback stuffs 
private FeedbackController feed; 

//tracking you... :) 
private WifiStalk stalk; 
private long lat; 
private long longitude; 

//Testing 
private DrawView dv; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.d("me","ultimap created!"); 
    master = null; 
    mgl = new MasterGL(this); //revisit this later for versatility 
    man = new Manual(this); 
    feed = new FeedbackController(this); 
    stalk = new WifiStalk(this); 
    draw = new PathCreator(this); 
    hv = new HomeView(this,draw); 
    try { 
     BeanCounter bean = new BeanCounter(this); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (XmlPullParserException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    showDialog(TUTORIAL); 
} 
@Override 
public boolean onKeyDown(int keyCode,KeyEvent e){ 
    if (keyCode == 82){ 

     if (viewDriverID.equals("hv")){ 
      hv.removeHV(); 
     } 
     else if (viewDriverID.equals("cv")){ 
      cv.removeCV(); 
     } 
     else if (viewDriverID.equals("mv")){ 
     return true; 
     } 
     else if (viewDriverID.equals("pcv")){ 
      return true; 
     } 

     if(man.getAddedState() == 0){ 

     //Show the manual code... 
     System.out.println("View we're coming from: " + this.getVDID()); 
     Log.e("me", "man.getaddedstate does equal 0, should be about to makeMan"); 

     man.makeMan();  
    } 

     else if(man.getAddedState() == 2){ 
     man.removeMan(); 
     man.removeMan2(); 
     man.setAddedState(1); 
    } 
     else if(man.getAddedState() == 1){ 
     System.out.println("View we're coming from: " + this.getVDID()); 
     man.addMan(); 
    } 
    } 
    return true; 
} 
@Override 
protected Dialog onCreateDialog(int id) { 
    //alerts ommitted for space 
} 

//Used to track the semantic context of what the Activity is displaying 
//Getters/setters for external access ommitted 

@Override 
protected void onStart(){ 
    super.onStart(); 
    Log.d("me","ultimap started!"); 
} 
@Override 
protected void onPause() { 
    super.onPause(); 
    Log.d("me","ultimap paused!"); 
    if (mgl.getGLview() != null){ 
      mgl.getGLview().onPause(); 
     } 
    if (draw.getGLV() != null){ 
     draw.getGLV().onPause(); 
    } 
} 
@Override 
protected void onResume() { 
    super.onResume(); 
    Log.d("me","ultimap resumed!"); 
    stalk.killListener(); 
    if (mgl.getGLview() != null){ 

      mgl.getGLview().onResume(); 
      Log.d("me", "mgl.getGLview is NOT null on resume"); 
     } 
    else if (mgl.getGLview() == null){ 
     mgl.initGL(); 
     mgl.getGLview().onResume(); 
     Log.d("me", "mgl.getGLview is null on resume"); 
    } 
    if (draw.getGLV() != null){ 
     draw.getGLV().onResume(); 
     Log.d("me", "draw.getGLV is NOT null on resume"); 
    } 
    else if (draw.getGLV() == null && draw.getHGL() != null){ 
      draw.pcvInit(); 
      Log.d("me", "draw.getGLV is null on resume"); 
    } 
    if (hv.getMV() != null && hv.getMV().getGLV() != null){ 
      hv.getMV().getGLV().onResume(); 
      Log.d("me", "map.getGLV is NOT null on resume"); 
     } 
     else if (hv.getMV() != null && hv.getMV().getGLV() == null && 
hv.getMV().getHGL() != null){ 
      hv.getMV().mvInit(); 
       Log.d("me", "map.getGLV is null on resume"); 
     } 
} 
@Override 
protected void onStop() { 
    super.onStop(); 
    //feed.getSP().release(); 
    Log.d("me","ultimap stopped!"); 
} 

@Override 
protected void onRestart(){ 
    super.onRestart(); 
    Log.d("me","ultimap restarted!"); 
    if (mgl != null){ 
      mgl.initGL(); 

     } 
} 
@Override 
protected void onDestroy(){ 
    super.onDestroy(); 
    Log.d("me","ultimap destroyed!"); 
    mgl.disposeTextures(); 
    if (feed.getSP() != null && feed.getSID() != 0 && feed.getLoaded() == 
true){ 
     feed.getSP().unload(feed.getSID()); 
     feed.getSP().release(); 
    } 
} 
} 

ट्यूटोरियल देखें प्रबंधक वर्ग:

/* 
* This class defines an in-app manual which is callable/dismissable 
* in a non-invasive way... 
* 
* http://www.codeproject.com/KB/android/ViewFlipper_Animation.aspx 
*http://developer.android.com/reference/android/widget/ 
*ViewFlipper.html#ViewFlipper%28android.content.Context%29 
* http://developer.android.com/resources/articles/avoiding-memory-leaks.html 
*/ 
package com.ai.ultimap.views; 
//imports ommitted 
public class Manual extends View implements OnItemClickListener{ 
private UltiMapActivity hUMA; 
private ListView lv1; 
private ListAdapter la; 
private LayoutInflater mInflater; 
private Vector<RowData> data; 
private TextView tv; 
private RelativeLayout holderRL; 
private View v; 
private View v2; 
private int addedState = 0; //tracks whether or not a view has been instantiated, 
    //and if so whether or not it is the currently visible view 
private int addedState2 = 0; 

//Grid View stuff 
private GridView helpGrid; 

//ViewFlipper stuff 
private ViewFlipper vf; 
private TextView tutTV; 
private String mapTutString = "Map View Tutorial Part: "; 
private String pcTutString = "Path Creator Tutorial Part: "; 
private String tutType; 
private TextView counterTV; 
private int partCounter = 1; 
private float oldTouchValue = 0.0f; 
private boolean searchOk = true; 
private ImageView floatingImage; 

public Manual(UltiMapActivity hAct){ 
    super(hAct); 
    hUMA = hAct; 
    holderRL = new RelativeLayout(hUMA); 
    v = new View(hUMA); 
    floatingImage = new ImageView(hUMA); 
} 
//Here we summon and populate the grid view 
    public void makeMan(){ 
     if (addedState == 0){ 
      Log.e("me", "in makeMan"); 
     mInflater = (LayoutInflater) 
hUMA.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
     hUMA.addContentView(holderRL, new 
LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); 
     v = mInflater.inflate(R.layout.helpgrid, holderRL, false); 
     helpGrid = (GridView) v.findViewById(R.id.manGV); 
     helpGrid.setAdapter(new ImageAdapter(hUMA)); 
     hUMA.addContentView(v, new 
LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); 
     helpGrid.setOnItemClickListener(this); 
     addedState = 2; 
     } 

    } 

public void addMan(){ 
    if (v != null && addedState == 1){ 
     v.setVisibility(VISIBLE); 
     v.bringToFront(); 
     addedState = 2; 
    } 
} 
public void addMan2(){ 
    if (v2 != null && addedState2 == 1){ 
     v2.setVisibility(VISIBLE); 
     v2.bringToFront(); 
     addedState2 = 2; 
    } 
} 
public void removeMan(){ 
    if (v != null && addedState == 2){ 
     v.setVisibility(GONE); 
     addedState = 1; 
     String s = hUMA.getVDID(); 
     if (s.equals("hv")){ 
      hUMA.getHome().addHV(); 
      Log.d("me", "add hjomeview called from anual"); 
      Log.d("me", "hv addedstate : " + 
hUMA.getHome().getAddedState()); 
     } 
     else if (s.equals("cv")){ 
      hUMA.getConfig().addCV(); 
     } 
     else if (s.equals("mv")){ 
      hUMA.getHome().getMV().mvInit(); 
     } 
     else if (s.equals("pcv")){ 
      hUMA.getDraw().pcvInit(); 
     } 
    } 
} 
public void removeMan2(){ 
    if (v2 != null && addedState2 == 2){ 
     v2.setVisibility(GONE); 
     addedState2 = 1; 
     String s = hUMA.getVDID(); 
     if (s.equals("hv")){ 
      hUMA.getHome().addHV(); 
      Log.d("me", "add hjomeview called from manual"); 
      Log.d("me", "hv addedstate : " + 
hUMA.getHome().getAddedState()); 
     } 
     else if (s.equals("cv")){ 
      hUMA.getConfig().addCV(); 
     } 
     else if (s.equals("mv")){ 
      hUMA.getHome().getMV().mvInit(); 
     } 
     else if (s.equals("pcv")){ 
      hUMA.getDraw().pcvInit(); 
     } 
    } 
} 

//addedstate getters and setters ommitted for space 

@Override 
    public boolean onTouchEvent(MotionEvent touchevent) { 

     switch (touchevent.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 

      { 
       System.out.println("received a touch down at " + touchevent.getX() 
+ "," + touchevent.getY()); 
       oldTouchValue = touchevent.getX(); 
       if(this.searchOk==false) return false; 
       float currentX = touchevent.getX(); 
       if (currentX > (vf.getWidth()/2)) 
       { 
        vf.setInAnimation(AnimationHelper.inFromRightAnimation()); 
        vf.setOutAnimation(AnimationHelper.outToLeftAnimation()); 
        vf.showNext(); 
        if (partCounter <= 3 && partCounter >= 1){ 
         partCounter++; 
        } 
        else if (partCounter == 4){ 
         partCounter = 1; 
        } 
        else{ 
         Log.e("me", "partCounter got past 4..."); 
        } 
        if(tutType.equals("map")){ 
         counterTV.setText(mapTutString + partCounter); 
        } 
        else if(tutType.equals("pc")){ 
         counterTV.setText(pcTutString + partCounter); 
        } 
        else{ 
         Log.e("me","not getting valid tutType string"); 
        } 
       } 
       if (currentX <= (vf.getWidth()/2)) 
       { 
        vf.setInAnimation(AnimationHelper.inFromLeftAnimation()); 
        vf.setOutAnimation(AnimationHelper.outToRightAnimation()); 

        vf.showPrevious(); 
        if (partCounter >= 2 && partCounter <= 4){ 
         partCounter--; 
        } 
        else if (partCounter == 1){ 
         partCounter = 4; 
        } 
        else{ 
         Log.e("me", "partCounter got below 1..."); 
        } 
        if(tutType.equals("map")){ 
         counterTV.setText(mapTutString + partCounter); 
        } 
        else if(tutType.equals("pc")){ 
         counterTV.setText(pcTutString + partCounter); 
        } 
        else{ 
         Log.e("me","not getting valid tutType string"); 
        } 

       } 

       break; 
      } 
      case MotionEvent.ACTION_UP: 
      { 
       //nothing to do here 
      } 
     } 
     return false; 
    } 

public void setUserText(String str){ 
    tv.setText(str); 
} 

private class CustomTV extends TextView{ 

    private String content = ""; 
    public CustomTV(Context c, String str){ 
     super(c); 
     content = str; 
     this.setText(content); 
    } 
} 

/** 
* Data type used for custom adapter. Single item of the adapter.  
*/ 
private class RowData { 
    protected String mItem; 
     protected String mDescription; 
     RowData(String item, String description){ 
     mItem = item; 
     mDescription = description;    
    } 

     @Override 
     public String toString() { 
       return mItem + " " + mDescription; 
     } 
} 

private class CustomAdapter extends ArrayAdapter<RowData> { 

    public CustomAdapter(Context context, int resource, 
        int textViewResourceId, List<RowData> objects) { 
      super(context, resource, textViewResourceId, objects); 

    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
      ViewHolder holder = null; 

      //widgets displayed by each item in your list 
      TextView item = null; 
      TextView description = null; 

      //data from your adapter 
      RowData rowData= getItem(position); 


      //we want to reuse already constructed row views... 
      if(null == convertView){ 
        convertView = mInflater.inflate(R.layout.custom_row, null); 
        holder = new ViewHolder(convertView); 
        convertView.setTag(holder); 
      } 
      holder = (ViewHolder) convertView.getTag(); 
      item = holder.getItem(); 
      item.setText(rowData.mItem); 
      description = holder.getDescription();   
      description.setText(rowData.mDescription); 
      return convertView; 
    } 
} 

/** 
* Wrapper for row data. 
* 
*/ 
private class ViewHolder {  
private View mRow; 
private TextView description = null; 
private TextView item = null; 

    public ViewHolder(View row) { 
    mRow = row; 
    } 

    public TextView getDescription() { 
      if(null == description){ 
        description = (TextView) mRow.findViewById(R.id.cbox); 
      } 
      return description; 
    } 

    public TextView getItem() { 
      if(null == item){ 
        item = (TextView) mRow.findViewById(R.id.cbox2); 
      } 
      return item; 
    }  
} 

@Override 
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) { 

v.setVisibility(GONE); 
if (addedState2 == 0){ 
hUMA.addContentView(this,DefineLayoutParams.getParams(DefineLayoutParams.getMM())); 
//this is why the onTouch only starts lsitening at this point 
if (position == 0){ 
v2 = mInflater.inflate(R.layout.flipper, holderRL, false); 
vf = (ViewFlipper) v2.findViewById(R.id.manFlipperVF); 
tutTV = (TextView) v2.findViewById(R.id.manDescriptionTV); 
counterTV = (TextView) v2.findViewById(R.id.mapviewtutCounterTV); 
tutTV.setText("Map View Instructions: ..."); 
counterTV.setText(mapTutString + partCounter); 
tutType = "map"; 
} 
else if (position == 1){ 
    v2 = mInflater.inflate(R.layout.flipperpc, holderRL, false); 
    vf = (ViewFlipper) v2.findViewById(R.id.manFlipperpcVF); 
    tutTV = (TextView) v2.findViewById(R.id.manDescriptionpcTV); 
    counterTV = (TextView) v2.findViewById(R.id.manFlipperCounterpcTV); 
    tutTV.setText("Path Creator Tutorial:..."); 
    counterTV.setText(pcTutString + partCounter); 
    tutType = "pc"; 
} 
addedState2 = 2; 
hUMA.addContentView(v2, DefineLayoutParams.getParams(DefineLayoutParams.getWW())); 
} 
else if(addedState2 == 1){ 
    v2.setVisibility(VISIBLE); 
    addedState2 = 2; 
} 
} 
public String getTutType(){ 
return tutType; 
} 
} 

ट्यूटोरियल देखें फ्लिपर एक्सएमएल:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 

> 
<ScrollView 
android:id="@+id/manDerscriptionSV" 
android:layout_width="match_parent" 
android:layout_height="200px" 
> 
<TextView 
android:id="@+id/manDescriptionTV" 
android:text="Coming Soon..." 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
/> 
</ScrollView> 
<TextView 
android:id="@+id/mapviewtutCounterTV" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:text="Map View Tutorial Part: " 
android:gravity="center" 
android:layout_below="@id/manDerscriptionSV" 
/> 
<ViewFlipper 
android:id="@+id/manFlipperVF" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:layout_below="@id/mapviewtutCounterTV" 
> 
<ImageView 
    android:id="@+id/mapviewtut1" 
    android:src="@drawable/mapviewtutflipper1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    /> 
<ImageView 
    android:id="@+id/mapviewtut2" 
    android:src="@drawable/mapviewtutflipper2" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    /> 
<ImageView 
    android:id="@+id/mapviewtut3" 
    android:src="@drawable/mapviewtutflipper3" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    /> 
<ImageView 
    android:id="@+id/mapviewtut4" 
    android:src="@drawable/mapviewtutflipper4" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    /> 


</ViewFlipper> 
</RelativeLayout> 

धन्यवाद, CCJ

+0

बहुत अच्छा सवाल है। – Mob

+0

इस दिशा में आंशिक नेतृत्व के रूप में: एंड्रॉइड पर प्रत्येक प्रक्रिया के पास वीएम, एर्गो, इसका स्वयं का जीसी का अपना उदाहरण है। – BRFennPocock

+0

आम तौर पर आपको ऑब्जेक्ट संदर्भ पर लंबे समय तक रखने का अच्छा विचार नहीं है। 'व्यूइन्फ्लेटर' जैसी चीजें और "xml I \ O" टिप्पणी के अंतर्गत वेरिएबल मुझे उन चीजों की तरह दिखती हैं जिनका अस्थायी रूप से उपयोग किया जाता है और फिर उन्हें त्याग दिया जा सकता है। यदि संभव हो, तो उन क्षेत्रों को हटा दें और उन्हें स्थानीय चर बना दें ताकि वे जितनी जल्दी हो सके कचरा इकट्ठा किया जा सके। –

उत्तर

23
  1. एंड्रॉइड में जीसी वास्तव में क्या ट्रिगर करता है?

यह एक आंतरिक कार्यान्वयन विस्तार है कि एसडीके डेवलपर्स को चिंता नहीं करनी चाहिए।

अन्य वीएम कार्यान्वयन मैंने आमतौर पर देखा है कि उनके जीसी को चलाने के लिए संकेत मिलने से पहले सिस्टम मेमोरी के एक निश्चित प्रतिशत को आवंटित किया जा सकता है।

मैं इसके लिए अपना शब्द ले जाऊंगा। जावा इस तरह से व्यवहार नहीं करता है। JVM परवाह नहीं है कि सिस्टम मेमोरी कितनी मौजूद है - यह केवल अपने स्वयं के वीएम के लिए अपने संभावित ढेर आकार (उदा। -Xmx) की परवाह करता है।

स्कैन निम्नलिखित LogCat तथापि Dalvik जीसी अक्सर भाग में कम से कम चल रहा

सही दिखाने के लिए लगता है। विशेष रूप से एंड्रॉइड के नए संस्करणों पर, जीसी पहले से किए गए स्टॉप-द-वर्ल्ड दृष्टिकोण के बजाए अपने धागे में एक साथ चलता है।

जीसी हाल ही में भागने के बाद से यह मुझे समझ में नहीं आता है और आवंटित कुछ भी नहीं है क्योंकि वीएम को 3 एमबी क्षमता (256 एमबी) के भीतर लाया जाना चाहिए था।

यह बेहद असंभव है कि आपके वीएम के लिए 256 एमबी हेप स्पेस है। आपके डिवाइस के आधार पर, यह 16 एमबी जितना कम हो सकता है।

इसके अलावा, एंड्रॉइड में एक कॉम्पैक्टिंग जीसी एल्गोरिदम नहीं है, और इसलिए यदि आपके पास 3 एमबी से अधिक उपलब्ध हो, तो आपके पास 3 एमबी ब्लॉक नहीं हो सकता है।

यही कारण है कि यह या तो recycle() अपने Bitmap वस्तुओं के लिए महत्वपूर्ण है या उन्हें पुन: उपयोग करने की कोशिश है (जैसे, BitmapOptions की inBitmap, एपीआई स्तर 11 में जोड़ा गया)।

इसके अलावा, आप डीडीएमएस का उपयोग एक ढेर डंप और मैट बनाने के लिए कर सकते हैं ताकि यह सुनिश्चित किया जा सके कि आपकी याददाश्त कहां जा रही है और कौन सा हो रहा है। यह एंड्रॉइड 3.0+ पर बेहतर काम करता है, क्योंकि मैट उन संस्करणों में Bitmap मेमोरी पर अधिक सटीक रूप से रिपोर्ट करने में सक्षम होगा।

क्या 256 एमबी सिस्टम रैम का केवल एक छोटा सा प्रतिशत है जो वास्तव में इसे दुर्घटनाग्रस्त होने से पहले वीएम को दिया जाता है?

हां। इसे ढेर कहा जाता है।एंड्रॉइड डिवाइसों में ढेर आकार सीमा है। आम तौर पर, यह एंड्रॉइड ओएस संस्करण और स्क्रीन रिज़ॉल्यूशन के आधार पर 16-48 एमबी रेंज में है।

क्या यह हो सकता है कि बिटमैप लोडिंग प्रक्रिया की अपनी याददाश्त आवंटन कैप हो?

नहीं, यह एक ही ढेर आकार के बजट से काम करता है। एंड्रॉइड 3.0 से शुरू होने पर, यह वास्तव में उसी ढेर से स्मृति को लोड करता है क्योंकि शेष दलविक वस्तुओं का उपयोग होता है - पहले, यह ढेर के बाहर सिस्टम रैम के ब्लॉक का उपयोग करता था, लेकिन अंतरिक्ष ढेर के आकार के बजट के खिलाफ गिना जाता था।

लेकिन वास्तव में क्या चलाता है Dalvik जीसी हम अभी भी ओएस में विश्वास की एक बहुत भयंकर डाल रहे हैं और प्रदर्शन के गूगल के अस्पष्ट विचार विमर्श सर्वोत्तम प्रथाओं

जानते हुए भी जीवन के बिना, के रूप में वे कहते हैं, पर चला जाता है ।

क्या जीसी स्थिति (उदाहरण के लिए 'चलाने के लिए', 'दौड़ना', 'समाप्त चलाना') कोड से ट्रैक किया जा सकता है ताकि बड़े संसाधन आवंटन को उपलब्ध स्मृति के आसपास रणनीतिक रूप से योजनाबद्ध किया जा सके? ... मैं जानना चाहता हूं कि एक समर्थित एपीआई कॉल कहीं है जहां कचरा कलेक्टर की सटीक स्थिति को ट्रैक करने के लिए उत्पादन कोड (केवल डीबग नहीं) पर भरोसा किया जा सकता है।

सं

जीसी हमेशा पूरे सिस्टम में है, या धागे (जैसे कि एक खेल के लिए एक समर्पित प्रतिपादन धागा के रूप में) को अलग कर सकते जीसी की वजह से संभावित प्रदर्शन अंतराल मुद्दों से बचने के?

जीसी किसी भी वीएम के लिए "सिस्टम-व्यापी" कभी नहीं है। जीसी हमेशा एक वीएम के भीतर है।

एंड्रॉइड के नए संस्करणों पर, जीसी समवर्ती है और इसलिए सामान्य परिस्थितियों में किसी भी धागे को भौतिक रूप से अवरुद्ध नहीं करेगा। एंड्रॉइड के पुराने संस्करणों पर, जीसी स्टॉप-द-वर्ल्ड है और सभी धागे को प्रभावित करेगा। एंड्रॉइड 3.0 के लिए निश्चित रूप से बदलाव आया था - मेरी याददाश्त इस बात पर अस्पष्ट है कि समवर्ती जीसी एंड्रॉइड 2.3 के लिए पहले से ही मौजूद है या नहीं। एंड्रॉइड में मेमोरी मैनेजमेंट पर एक 2011 Google I | O प्रस्तुति है जिसे आप देखना चाहते हैं।

क्या यह वीएम को दुर्घटनाग्रस्त कर देगा या क्या ओएस इस तरह की चरम स्थितियों को स्वचालित रूप से वीएम को दुर्घटनाग्रस्त होने से बचाने के लिए है?

एंड्रॉइड को OutOfMemoryException बढ़ाने से पहले तत्काल जीसी को मजबूर करना चाहिए। यह परिदृश्य मेरे पिछले पैराग्राफ के अनुसार "सामान्य परिस्थितियों" के रूप में योग्य नहीं है।

+0

सूचनात्मक उत्तर के लिए धन्यवाद! क्या आप जानते हैं कि जेएनआई कैसे Dalvik वीएम स्मृति उपयोग में संबंध है? मूल कोड अपनी याददाश्त का प्रबंधन करना चाहिए, लेकिन क्या यह स्मृति किसी एप्लिकेशन के ढेर अंतरिक्ष बजट के विरुद्ध गिना जाता है?यदि हां, तो क्या मूल थ्रेड द्वारा आवंटित एंड्रॉइड फोर्स-फ्री मेमोरी हो सकती है यदि वह थ्रेड बहुत अधिक आवंटित करने का प्रयास करता है या यह स्थिति (अंत में/शायद) सिस्टम क्रैश की ओर ले जाती है? – CCJ

+1

@CCJ: "क्या यह स्मृति किसी एप्लिकेशन के ढेर स्पेस बजट के विरुद्ध गिना जाता है?" - अगर यह वास्तव में मूल स्मृति है (उदाहरण के लिए, 'malloc() '), तो मेरी समझ यह है कि यह ढेर सीमा के खिलाफ नहीं है। हालांकि, मैं जेएनआई/एनडीके विशेषज्ञ नहीं हूं। – CommonsWare

+0

हम्म ... ठीक है, मुझे उस मामले को आगे बढ़ाना होगा। धन्यवाद! – CCJ

संबंधित मुद्दे