Suspending all threads took: ms warning using Threads - Android
The first line is basically saying that the garbage collector (GC) decided it needed to suspend all threads to do some of its work (such as relocating variables) and that took some time. Normally there's a number there.
The second line is the result of the collection. It freed a fair amount of memory, and you now have 1/3 of your heap free. It required your app to be paused for 2ms, and in total spent 127 ms collecting garbage.
GC in and of itself isn't bad. But if you're doing it all the time, either you're doing something with lots of memory required or you're doing something inefficiently. Heavy string parsing, especially for something like JSoup, can cause lots of small objects (mainly strings) to be made that really required cleanup quickly on a small memory device like a phone, so it isn't surprising to see here.
Basically, this is only a problem if you're getting performance hiccups from GC or if you're going OOM at some point. If neither of those are happening, I wouldn't worry about this yet.
Comments
-
God almost 4 years
I have 2
Thread
s that make some network computation. When I run my app and after starting my secondThread
I get a:Suspending all threads took: ms
warning followed by:Background sticky concurrent mark sweep GC freed 246745(21MB) AllocSpace objects, 169(6MB) LOS objects, 33% free, 31MB/47MB, paused 1.972ms total 127.267ms
warning.Sometimes I get just those 2 warnings and other times I get a lot of those 2 warnings until I decide to terminate the app running. At this point, it's just running the main
Thread
and basically doing nothing. Here is the relevant code:MainActivity.java:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Getting html page through a thread this.getHtmlPageThread = new GetHtmlPageThread(URL_STRING); this.getHtmlPageThread.start(); // The thread that will search the web for data this.getDataFromTheWebThread = new GetDataFromTheWebThread(); // Search button click listener searchButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Get the searched lyrics searchedLyrics = inputEditText.getText().toString(); informUserAboutConnectionToTheNet(); // Starting to search the web for data through a thread getDataFromTheWebThread.start(); if (!getDataFromTheWebThread.isAlive()) { printMap(MainActivity.matchResultMap); } } }); // End of search button click listener printMap(MainActivity.matchResultMap); } // End of onCreate() method protected void onStart() { super.onStart(); if (!this.isParseSucceeded()) // Connection to net failed { if (!getHtmlPageThread.isAlive()) // If the thread is not alive, start it. { getHtmlPageThread.start(); // Try to connect again this.informUserAboutConnectionToTheNet(); } } if (!this.isParseSucceeded()) { super.onStart(); // Call onStart() method } } // End of onStart() method
GetHtmlPageThread.java:
public class GetHtmlPageThread extends Thread { private String url; public GetHtmlPageThread(String url) { this.url = url; } @Override public void run() { try { MainActivity.htmlPage.setHtmlDocument(this.getParsedDocument(this.url)); if (MainActivity.htmlPage.getHtmlDocument() != null) { MainActivity.parsedSucceeded = true; // Parsed succeeded } else { MainActivity.parsedSucceeded = false; // Parsed failed } Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } /** * Returns the document object of the url parameter. * If the connection is failed , return null. * * @param url Url to parse * @return The document of the url. * */ public Document getParsedDocument(String url) { try { return Jsoup.connect(url).get(); } catch (IOException e) // On error { e.printStackTrace(); } return null; // Failed to connect to the url } }
GetDataFromTheWeb.java:
public class GetDataFromTheWebThread extends Thread { public static boolean isFinished = false; // False - the thread is still running. True - the thread is dead @Override public void run() { GetDataFromTheWebThread.isFinished = false; try { this.getLyricsPlanetDotComResults(MainActivity.searchedLyrics); // Method for internet computations Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } GetDataFromTheWebThread.isFinished = true; } ... }
Basically the
this.getLyricsPlanetDotComResults(MainActivity.searchedLyrics);
method in the secondThread
is doing a lot of the internet work and computations in general. More computations than net stuff to be exact.So I guess I got those warnings because the second
Thread
is too "Busy"? Or maybe just my implementation with the activity life cycle with theonCreate()
method andonStart()
method are wrong?Needless to say, I don't get the output I want, though I debugged the app and stepped through the second
Thread
and it works Perfectly. So again, it got to be something with myActivity
's implementation. -
God about 8 yearsOk I get it. But still, When i debug I can see my
Thread
is doing exactly what i want(**To update a global variable inMainActivity.java
) , I just don't know when i can access it(When theThread
is done It's work) and how(Because i will need aLoop
like that -while (!myThread,isAlive()) {//Do my work}
, but it is a good implementation? Also i thogh about changing theThread
toHandlerThread
developer.android.com/intl/zh-cn/reference/android/os/… . What do you think? Thanks. -
Gabe Sechan about 8 yearsIf you need to know when the thread is done, use a callback (or if you need a notification on the UI thread, a callback made from a Handler on the UI thread). HandlerThread is more for a thread where you're going to send it a series of events it has to respond to.
-
God about 8 yearsstackoverflow.com/questions/19366301/… Just like here?
-
God about 8 yearsOr in here stackoverflow.com/questions/3398363/…?