Android application Thread CPU GC operatiing and OOM Question 0603-Handy notes

Source: Internet
Author: User

Before the app finishes the test, run through the entire aging phase, including data transmission and dispatch, type adb shell top-m 5 found my app PID occupied

CPU is the most, in fact, I want to say that writing an app is not difficult, you do not have a comprehensive analysis of the memory usage of the app? Avoid problems such as oom, and other possible

can bring about some of the occasional problems that some estimates a lot of small partners have not considered, nothing, today to everyone to talk about this aspect of things, although not what difficult

knowledge points, but the most important thing is to develop this kind of habit, in order to reduce unnecessary waste of time in the subsequent development, I will take you how to find and solve the question

Problem, step by step analysis


First look at the CPU usage of our app:


We can see com.digissin.twelve this process is always ranked first, this is the process of our testing, below I take the small friends how to find out to ask

Correct the problem in a timely manner.


First, let's analyze why CPU usage is so high. Is there too much time-consuming operation on the main thread or sub-thread, network operation, new instance object?

With this question, let's look at DDMS and analyze:



View Com.digissin.twelve.rsudpprotocol&postbytesthread 134 lines of code:



The dead loop is caused by the read state, but it cannot be removed because the app needs this dead loop to communicate to the server, as long as it is not an accident, the app is

Keep communication with the backstage! When there is data coming in, Ispause will be set to true, and the code flow will go to if, once a datagram is sent out,

Ispause false While it is used to enter the empty loop, do nothing, and the frequency of the loop executes quickly, if we call sleep in this dead loop ()

Although successful, it is clear that it runs counter to the needs of the app, so it must be ruled out, because once you enter the sleep () thread, you don't work, from the main line

It doesn't make any sense to send a datagram sent by agreement! So this is not the way to take it.


So I quickly thought of a way, that is, when ispause false, we do not need sub-threading work, it is very simple, I just need to let him hibernate, once

There are datagrams coming from the protocol, and we're wakeup to let the child threads continue to work, and that's not wait () and notify () are the first to differentiate between thread and

Object of these two things inside of Wait () and notify (), source analysis is too general, I give you examples of analysis

Calling these 22 functions directly in thread is not going to work, we need to create an object to manage the pauses and continuation of the child threads, which means

A child thread is the equivalent of an ordinary employee, and a new object object is the equivalent of a manager who needs to be notified and informed by the manager, even if the member

Workers know what they want to do next, they need the permission of the manager! Employees can not be independent, just can't do their own things,

Otherwise the entire management mode will be messed up, so we have to create an object to do this pause and continue control on the child thread.


So I loads the synchronized field to this inner class line and add an instanced static method to create this object (Postbytesthread) instance

and give the pause and resume functions:

        private static Postbytesthread mthreadinstance = null;              Public synchronized static Postbytesthread Getthreadinstance () {if (mthreadinstance = = null) {              Mthreadinstance = new Postbytesthread ();          } return mthreadinstance; } public synchronized Boolean ispause () {return ispause;} Public synchronized void Setpause (Boolean ispause) {this.ispause = Ispause;} Public byte[] Getpost_bytes () {return post_bytes;} public void Setpost_bytes (byte[] post_bytes) {this.post_bytes = post_bytes;} Public synchronized void Onthreadpause () {try {log.e (TAG, tag+ "onthreadpause ()----"); this.wait ();} catch ( Interruptedexception e) {log.i (TAG, e.tostring ());}}    Public synchronized void Onthreadresume () {LOG.E (TAG, tag+ "onthreadresume ()----"); this.notify ();            @Override public void Run () {if (Udpsocket = = null) {LOG.I (TAG, tag+ "Udpsocket is null");            Return   } while (true) {     LOG.I (TAG, tag+ "Ispause () state:" +ispause ());        if (Ispause ()) {try {sendpacket.setdata (getpost_bytes ());        Sendpacket.setlength (Getpost_bytes (). length);        Sendpacket.setaddress (serveraddress);        Sendpacket.setport (DEFAULT_POTR);        Udpsocket.send (Sendpacket);        Thread.Sleep (1000);        Setpause (FALSE);        } catch (Interruptedexception e) {log.i (TAG, "Exception:" +e.tostring ());        } catch (IOException e) {log.i (TAG, "Exception:" +e.tostring ());        }}else{Onthreadpause (); }}    }    }

Call method, callback interface received from the main thread protocol message packet distribution, and began to work, of course, just for the convenience of everyone to watch, in fact, the start () method does not have to be sent here, because this synchronization object only in the child thread extinction will be recycled, So the equivalent of each time to judge the synchronization of the instance of the object situation

    public void Setpostbytesdata (byte[] data) {    postbytesthread.getthreadinstance (). Start ();    Postbytesthread.getthreadinstance (). Onthreadresume ();    Postbytesthread.getthreadinstance (). Setpause (true);    Postbytesthread.getthreadinstance (). setpost_bytes (data);    Boolean ispause = Postbytesthread.getthreadinstance (). Ispause ();    LOG.D ("Postbytesthread", "Postbytesthread  Ispause () state:" +ispause);    }

After processing this code we continue to look at CPU usage:


We can see that the CPU consumption of the com.digissin.twelve has been greatly reduced, so as to achieve our goal, in solving this problem, I also tell you a

Often made mistakes, and in the form of code and comments to everyone to see clearly

To create an unnecessary new instance:

In the case of some progress bar updating or uploading the download data, we usually need to keep the UI new and so on, which involves the interaction of the child thread with handler, which needs

We are constantly sending a message object to the handler, which makes it easy to make this error, as follows:

@Overridepublic void Run () {while (true) {try {settinglocationtime ()} catch (Interruptedexception e) {E.printstacktrace ();}}} private void Settinglocationtime () throws Interruptedexception{if (Handler!=null) {SendMessage (post_data); time = SETTING_TIME>0?SETTING_TIME:DEFAULT_TIME;//LOG.I (TAG, tag+ "Settinglocationtime () Time:" +time); Thread.Sleep (time*1000);}} /** * This function will run in run while (true) * Message\bundle will be constantly creating new instance objects * So this is a very low error! It's deadly, too! * */private void SendMessage (byte[]data) {Byte[]_data=byteparsebeantools.postprotocolbyte ( Byteprotocolsessiontype.location_state_send, data); Message msg = new Message ();  Unnecessary Message new instance object Msg.what=mainsessionutil.send_post_byets_data; Bundle bundle = new bundle (); Unnecessary bundle new Instance Object Bundle.putbytearray (Mainsessionutil.bytes_data_key, _data); Msg.setdata (bundle); Handler.sendmessage (msg);}

Solution:

@Overridepublic void Run () {while (true) {try {settinglocationtime ()} catch (Interruptedexception e) {E.printstacktrace ();}}} private void Settinglocationtime () throws Interruptedexception{if (Handler!=null) {SendMessage (post_data); time = SETTING_TIME>0?SETTING_TIME:DEFAULT_TIME;//LOG.I (TAG, tag+ "Settinglocationtime () Time:" +time); Thread.Sleep (time*1000);}} /** * You can put the bundle in the place where class is loaded, instantiate the object * Once the data is loaded, execute the clear () function before the next call, and the bundle object is equivalent to an iron bowl * each loaded with different water. It avoids having to open up new memory space each time to hold the bundle object * The Message object is simpler, because I callback a handler object, we can directly call the handler object's Obtainmessage () function, This function when handler is created, whether you use it or not, it is there * dies with handler, does not need to be instantiated, does not need to be created, can be taken directly out of the use, which avoids each time to open up a new memory space * To load the message object, Obtainmessage () function from Messagepool * **/private void SendMessage (byte[]data) {bundle.clear ();//Pour out the old water in the bowl (empty the previous cache), fill in the new water (populate the new data from the callback function) Byte[]_data=byteparsebeantools.postprotocolbyte (byteprotocolsessiontype.location_state_send, data);  Message msg = Handler.obtainmessage (); From Messagepoolmsg.what=mainsessionutil.send_post_byets_data;bundLe.putbytearray (Mainsessionutil.bytes_data_key, _data);//Install new water (fill new data source) Msg.setdata (bundle); Handler.sendmessage ( msg);}

This way the CPU consumption problem can be greatly reduced, so that the problem can be solved!


Android application Thread CPU GC operatiing and OOM Question 0603-Handy notes

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.