web-dev-qa-db-ja.com

すべてのスレッドを一時停止しました:スレッドを使用したms警告-Android

ネットワーク計算を行う2つのThreadsがあります。アプリを実行し、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番目のThreadthis.getLyricsPlanetDotComResults(MainActivity.searchedLyrics);メソッドは、一般に多くのインターネット作業と計算を実行しています。正確には、ネットのものよりも多くの計算。

2番目のThreadが「ビジー」すぎるため、これらの警告が表示されたと思いますか?それとも、onCreate()メソッドとonStart()メソッドを使用したアクティビティライフサイクルの実装が間違っているのでしょうか。

言うまでもなく、アプリをデバッグして2番目のThreadをステップ実行し、動作しますが、必要な出力が得られません完全に。繰り返しになりますが、それは私のActivityの実装で何かになるはずです。

6
God

最初の行は基本的に、ガベージコレクター(GC)が、一部の作業(変数の再配置など)を実行するためにすべてのスレッドを一時停止する必要があると判断し、それに時間がかかったことを示しています。通常、そこには番号があります。

2行目は、コレクションの結果です。かなりの量のメモリが解放され、ヒープの3分の1が解放されました。アプリを2ミリ秒間一時停止する必要があり、合計で127ミリ秒かけてゴミを収集しました。

GC自体は悪くありません。しかし、それを常に実行している場合は、大量のメモリが必要なことを実行しているか、非効率的に実行しています。特にJSoupのような重い文字列解析では、電話などの小さなメモリデバイスですばやくクリーンアップする必要のある小さなオブジェクト(主に文字列)が多数作成される可能性があるため、ここを参照してください。

基本的に、これは、GCからパフォーマンスの問題が発生している場合、またはある時点でOOMになる場合にのみ問題になります。どちらも起こらなければ、私はまだこれについて心配しません。

10
Gabe Sechan