Java 暂停所有线程需要:使用线程的毫秒警告 - Android

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36652766/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:31:59  来源:igfitidea点击:

Suspending all threads took: ms warning using Threads - Android

javaandroidmultithreadinggarbage-collectionjsoup

提问by God

I have 2 Threads that make some network computation. When I run my app and after starting my second ThreadI get a:

我有 2Thread秒进行一些网络计算。当我运行我的应用程序并启动我的第二个应用程序后,Thread我得到:

Suspending all threads took: mswarning followed by:

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.267mswarning.

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警告。

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 Threadand basically doing nothing. Here is the relevant code:

有时我只收到那 2 个警告,而有时我收到很多这 2 个警告,直到我决定终止应用程序运行。在这一点上,它只是运行主要的Thread,基本上什么都不做。这是相关的代码:

MainActivity.java:

主活动.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:

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:

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 Threadis doing a lot of the internet work and computations in general. More computations than net stuff to be exact.

基本上,this.getLyricsPlanetDotComResults(MainActivity.searchedLyrics);第二种方法Thread是做大量的互联网工作和计算。确切地说,比净东西更多的计算。

So I guess I got those warnings because the second Threadis too "Busy"? Or maybe just my implementation with the activity life cycle with the onCreate()method and onStart()method are wrong?

所以我想我收到这些警告是因为第二个Thread太“忙”了?或者也许只是我的活动生命周期的onCreate()方法和onStart()方法的实现是错误的?

Needless to say, I don't get the output I want, though I debugged the app and stepped through the second Threadand it works Perfectly. So again, it got to be something with my Activity's implementation.

不用说,我没有得到我想要的输出,尽管我调试了应用程序并逐步完成了第二个Thread并且它完美地工作。再说一次,它必须与 myActivity的实现有关。

采纳答案by Gabe Sechan

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.

第一行基本上是说垃圾收集器 (GC) 决定它需要挂起所有线程来完成它的一些工作(例如重定位变量),这需要一些时间。通常那里有一个数字。

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.

第二行是收集的结果。它释放了相当多的内存,您现在有 1/3 的堆空闲。它需要您的应用程序暂停 2 毫秒,并且总共花费 127 毫秒来收集垃圾。

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.

GC 本身并不坏。但是,如果您一直都在这样做,那么您要么是在做需要大量内存的事情,要么是在做一些效率低下的事情。繁重的字符串解析,尤其是对于 JSoup 之类的东西,可能会导致大量小对象(主要是字符串)被生成,这些对象确实需要在手机等小型存储设备上快速清理,因此看到这里并不奇怪。

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.

基本上,这只是一个问题,如果您从 GC 中遇到性能问题,或者您在某个时候会出现 OOM。如果这两种情况都没有发生,我还不会担心这个。