ネットワーク計算を行う2つのThread
sがあります。アプリを実行し、2番目のThread
を開始した後、次のようになります。
_Suspending all threads took: ms
_警告の後に:
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
警告。
アプリの実行を終了するまで、2つの警告だけが表示されることもあれば、2つの警告が多数表示されることもあります。この時点では、メインのThread
を実行しているだけで、基本的には何もしていません。関連するコードは次のとおりです。
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;
}
...
}
_
基本的に、2番目のThread
のthis.getLyricsPlanetDotComResults(MainActivity.searchedLyrics);
メソッドは、一般に多くのインターネット作業と計算を実行しています。正確には、ネットのものよりも多くの計算。
2番目のThread
が「ビジー」すぎるため、これらの警告が表示されたと思いますか?それとも、onCreate()
メソッドとonStart()
メソッドを使用したアクティビティライフサイクルの実装が間違っているのでしょうか。
言うまでもなく、アプリをデバッグして2番目のThread
をステップ実行し、動作しますが、必要な出力が得られません完全に。繰り返しになりますが、それは私のActivity
の実装で何かになるはずです。
最初の行は基本的に、ガベージコレクター(GC)が、一部の作業(変数の再配置など)を実行するためにすべてのスレッドを一時停止する必要があると判断し、それに時間がかかったことを示しています。通常、そこには番号があります。
2行目は、コレクションの結果です。かなりの量のメモリが解放され、ヒープの3分の1が解放されました。アプリを2ミリ秒間一時停止する必要があり、合計で127ミリ秒かけてゴミを収集しました。
GC自体は悪くありません。しかし、それを常に実行している場合は、大量のメモリが必要なことを実行しているか、非効率的に実行しています。特にJSoupのような重い文字列解析では、電話などの小さなメモリデバイスですばやくクリーンアップする必要のある小さなオブジェクト(主に文字列)が多数作成される可能性があるため、ここを参照してください。
基本的に、これは、GCからパフォーマンスの問題が発生している場合、またはある時点でOOMになる場合にのみ問題になります。どちらも起こらなければ、私はまだこれについて心配しません。