Android一个APP里面最少有几个线程
参考
https://www.jianshu.com/p/92bff8d6282f
https://www.jianshu.com/p/8a820d93c6aa
线程查看
Android一个进程里面最少包含5个线程,分别为:
- main线程(主线程)
- FinalizerDaemon线程
终结者守护线程。对于重写了成员函数finalize的对象,它们被GC决定回收时,并没有马上被回收,而是被放入到一个队列中,等待FinalizerDaemon守护线程去调用它们的成员函数finalize,然后再被回收。 - FinalizerWatchdogDaemon线程
监控终结者守护线程。用来监控FinalizerDaemon线程的执行。一旦检测那些重定了成员函数finalize的对象在执行成员函数finalize时超出一定的时候,那么就会退出VM。 - HeapTaskDaemon线程
堆栈守护线程。用来执行堆栈的操作,也就是用来将那些空闲的堆内存归还给系统。 - ReferenceQueueDaemon线程。
引用队列守护线程。我们知道,在创建引用对象的时候,可以关联一个队列。当被引用对象引用的对象被GC回收的时候,被引用对象就会被加入到其创建时关联的队列去。这个加入队列的操作就是由ReferenceQueueDaemon守护线程来完成的。这样应用程序就可以知道哪些被引用对象引用的对象已经被回收了。
下图是创建的一个仅有hello World!页面的工程,线程包含以下的这些。
刚开始我比较疑惑的是FileObserver 这个线程是否也是每个进程所必须包含的线程。后来我查看了一下Daemons创建的过程,能确定的是Android启动一个APP最少包含ReferenceQueueDaemon线程、FinalizerDaemon线程、FinalizerWatchdogDaemon线程、HeapTaskDaemon线程,以及在ActivityThread中开启的主线程。如下:
public final class Daemons {private static final int NANOS_PER_MILLI = 1000 * 1000;private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;public static void start() {ReferenceQueueDaemon.INSTANCE.start();//开启ReferenceQueueDaemon线程FinalizerDaemon.INSTANCE.start();//开启FinalizerDaemon线程FinalizerWatchdogDaemon.INSTANCE.start();//开启FinalizerWatchdogDaemon线程HeapTaskDaemon.INSTANCE.start();//开启HeapTaskDaemon线程}public static void startPostZygoteFork() {ReferenceQueueDaemon.INSTANCE.startPostZygoteFork();FinalizerDaemon.INSTANCE.startPostZygoteFork();FinalizerWatchdogDaemon.INSTANCE.startPostZygoteFork();HeapTaskDaemon.INSTANCE.startPostZygoteFork();}public static void stop() {HeapTaskDaemon.INSTANCE.stop();ReferenceQueueDaemon.INSTANCE.stop();FinalizerDaemon.INSTANCE.stop();FinalizerWatchdogDaemon.INSTANCE.stop();}...
}
1.main线程
2. ReferenceQueueDaemon线程。
代码块
3. FinalizerDaemon线程
private static class FinalizerDaemon extends Daemon {private static final FinalizerDaemon INSTANCE = new FinalizerDaemon();private final ReferenceQueue<Object> queue = FinalizerReference.queue;private final AtomicInteger progressCounter = new AtomicInteger(0);// Object (not reference!) being finalized. Accesses may race!private Object finalizingObject = null;FinalizerDaemon() {super("FinalizerDaemon");}@Override public void runInternal() {// This loop may be performance critical, since we need to keep up with mutator// generation of finalizable objects.// We minimize the amount of work we do per finalizable object. For example, we avoid// reading the current time here, since that involves a kernel call per object. We// limit fast path communication with FinalizerWatchDogDaemon to what's unavoidable: A// non-volatile store to communicate the current finalizable object, e.g. for// reporting, and a release store (lazySet) to a counter.// We do stop the FinalizerWatchDogDaemon if we have nothing to do for a// potentially extended period. This prevents the device from waking up regularly// during idle times.// Local copy of progressCounter; saves a fence per increment on ARM and MIPS.int localProgressCounter = progressCounter.get();while (isRunning()) {try {// Use non-blocking poll to avoid FinalizerWatchdogDaemon communication// when busy.FinalizerReference<?> finalizingReference = (FinalizerReference<?>)queue.poll();if (finalizingReference != null) {finalizingObject = finalizingReference.get();progressCounter.lazySet(++localProgressCounter);} else {finalizingObject = null;progressCounter.lazySet(++localProgressCounter);// Slow path; block.FinalizerWatchdogDaemon.INSTANCE.goToSleep();finalizingReference = (FinalizerReference<?>)queue.remove();finalizingObject = finalizingReference.get();progressCounter.set(++localProgressCounter);FinalizerWatchdogDaemon.INSTANCE.wakeUp();}doFinalize(finalizingReference);} catch (InterruptedException ignored) {} catch (OutOfMemoryError ignored) {}}}@FindBugsSuppressWarnings("FI_EXPLICIT_INVOCATION")private void doFinalize(FinalizerReference<?> reference) {FinalizerReference.remove(reference);Object object = reference.get();reference.clear();try {object.finalize();} catch (Throwable ex) {// The RI silently swallows these, but Android has always logged.System.logE("Uncaught exception thrown by finalizer", ex);} finally {// Done finalizing, stop holding the object as live.finalizingObject = null;}}}
4. FinalizerWatchdogDaemon线程
代码块
5. HeapTaskDaemon线程
private static class HeapTaskDaemon extends Daemon {private static final HeapTaskDaemon INSTANCE = new HeapTaskDaemon();HeapTaskDaemon() {super("HeapTaskDaemon");}// Overrides the Daemon.interupt method which is called from Daemons.stop.public synchronized void interrupt(Thread thread) {VMRuntime.getRuntime().stopHeapTaskProcessor();}@Override public void runInternal() {synchronized (this) {if (isRunning()) {// Needs to be synchronized or else we there is a race condition where we start// the thread, call stopHeapTaskProcessor before we start the heap task// processor, resulting in a deadlock since startHeapTaskProcessor restarts it// while the other thread is waiting in Daemons.stop().VMRuntime.getRuntime().startHeapTaskProcessor();}}// This runs tasks until we are stopped and there is no more pending task.VMRuntime.getRuntime().runHeapTasks();}}
查看VMRuntime的源码发现 startHeapTaskProcessor()、runHeapTasks()均是native方法。
public native void requestConcurrentGC();public native void concurrentGC();public native void requestHeapTrim();public native void trimHeap();public native void startHeapTaskProcessor();public native void stopHeapTaskProcessor();public native void runHeapTasks();
如何查看当前项目包含几个线程
在Android studio中点击Profile 图标,点击 CPU,显示如下图,点击 Record,然后再点击 Stop,即可生成。