I have 2 Thread
s that make some network computation.
When I run my app and after starting my second Thread
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 second Thread
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 the onCreate()
method and onStart()
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 my Activity
's implementation.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With