【问题标题】:How to make Java Thread Dump in Android?如何在 Android 中制作 Java 线程转储?
【发布时间】:2012-11-27 16:50:34
【问题描述】:

我只想从 java 虚拟机线程中获取所有转储,查看线程锁定的内容以及等待解锁某些资源的线程。类似的东西被描述为here。 我试图杀死 Zygote 进程,但没有结果。

【问题讨论】:

    标签: java android dump


    【解决方案1】:

    最简单的方法是使用 DDMS,或 Eclipse 中的 ADT 插件。有关基本说明,请参阅http://developer.android.com/tools/debugging/ddms.html。简而言之,进入设备视图,选择您感兴趣的应用程序,确保启用线程更新,然后切换到线程视图。您将在该进程中获得实时更新的线程列表。双击线程将抓取当前堆栈状态的快照。

    您可以在线程转储中使用全选和复制来复制和粘贴堆栈跟踪。

    如果你有一个开发者/root 设备,你可以通过向你感兴趣的应用进程发送SIGQUIT 请求 Dalvik VM 转储线程堆栈。例如,如果你想查看所有的堆栈日历应用程序中的线程,您可以执行以下操作:

    % adb shell ps | grep android.calendar
    u0_a6     2596  127   912804 48296 ffffffff b6f62c10 S com.google.android.calendar
    # 2596 is the process ID
    % adb shell run-as com.google.android.colendar kill -3 2596
    

    logcat 输出会这样说:

    I/dalvikvm( 2596): Wrote stack traces to '/data/anr/traces.txt'
    

    所以,拉那个:

    % adb pull /data/anr/traces.txt .
    

    每次您发出进程信号时,日志都会附加到该文件中。里面可能还有其他东西,需要搜索pid 2596

    ----- pid 2596 at 2012-11-27 12:48:38 -----
    Cmd line: com.google.android.calendar
    
    DALVIK THREADS:
    ...
    

    与 DDMS 线程视图相比,这样做的好处是,如果线程卡在监视器上,堆栈转储将为您提供有关锁定的对象以及当前持有锁定的线程的指示。

    zygote 进程在这里不相关;根据定义,它没有运行应用程序。由于它没有 JDWP 线程,并且不监听 SIGQUIT,因此无论如何您都无法从中获取堆栈跟踪。

    【讨论】:

    • 注意:我在 /data/anr/traces.txt.bugreport 找到了我的踪迹
    • 这将为不可调试的应用程序返回“run-as: package not debuggable: $package”。
    【解决方案2】:

    只需在 Android Studio 中调试您手机上的应用即可;然后在“调试视图”Alt+5 中,只需按下左下角的“相机”按钮,即可获取所有堆栈跟踪的转储,包括它们持有的锁。

    【讨论】:

    • 使用 IntelliJ IDEA 或 Android Studio 的最佳答案(最简单的解决方案)。
    【解决方案3】:

    answer 获取命令,并将它们放在一起,这是以下脚本。将其放入 dump.sh 文件并执行,它将找到所需的 PID,创建一个具有当前时间戳的新文件,然后将 Thread-Dump 提取到其中。 当一个人有很短的时间来获取转储时,这个命令会很有用。 在使用它之前,请确保将跟踪放入文件/data/anr/traces.txt 或在脚本中替换此值。

    #!/bin/sh
    
    pid=`./adb shell ps | grep android.calendar | awk '{print $2}'`
    echo $pid
    f=$(date +%s%N)
    echo $f
    ./adb shell run-as com.google.android.calendar kill -3 $pid
    ./adb pull /data/anr/traces.txt $f
    

    作为替代文件名,可以使用f=$(date +"%T.%6N") 来获取人类可读的时间戳。找到需要的文件会更容易。

    【讨论】:

    • 有时你不能使用断点。对于这些情况,您可以使用此脚本。
    【解决方案4】:

    如果您没有根设备并且您的应用不是调试版本,您仍然可以从开发人员选项生成错误报告以获取线程转储。转储位于 bugreport*.txt 文件的 VM TRACES JUST NOW 部分下。

    如果您知道您怀疑的线程的 ID,它会更快。您可以通过调用获取应用的PID:

    adb shell ps -A | grep com.example.myapp
    

    以及线程 ID:

    adb shell ps -T | grep <pid>
    

    【讨论】:

      【解决方案5】:

      如果您切换到 Eclipse 中的 DDMS 视图,您有一些工具可以查看线程。这就是你要找的吗?

      【讨论】:

      • 几乎是的。我还不知道什么对象被锁定了,例如:-locked (a java.io.InputStreamReader)
      • 这个答案已经过时了,因为不再有 Eclipse。
      • Eclipse 消失了,但 DDMS 仍然存在,没有足够的替代品。
      【解决方案6】:

      我猜您需要应用程序中的线程。为此,您可以使用 ADT eclipse 插件上的 DDMS 视图。这是文档http://developer.android.com/tools/debugging/ddms.html#thread

      【讨论】:

      • 几乎是的。我还不知道对象被锁定了什么,例如:-locked (a java.io.InputStreamReader)
      • Eclipse 和 DDMS 已弃用,Android Profiler 不会显示任何内容。请阅读下面的答案。
      • Eclipse 消失了,但 DDMS 仍然存在,没有足够的替代品。
      猜你喜欢
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 2011-10-22
      • 1970-01-01
      相关资源
      最近更新 更多