Android Profiling : what are FinalizerDaemon, FinalizerWatchDogDaemon,ReferenceQueueDaemon,Different binders and JDWP? - android

I am implementing one library for Applications. Traceview after application is using the library looks like :
If I am not using the library, Only main thread is shown in the traceview. So what are these different Daemons,JDWP and Binders and when these are started by Android OS ?

FinalizerDaemon is used to abort if any finaliser is running longer.
FinalizerWatchdog is watch dog service for finaliser daemon.
JDWP is java debugger service.
ReferenceQueueDaemon is heap management thread moves elements from the garbage collector's pending list to the managed reference queue.
Not sure about binders.
More details at https://android.googlesource.com/platform/libcore/+/a7752f4d22097346dd7849b92b9f36d0a0a7a8f3/libdvm/src/main/java/java/lang/Daemons.java

Related

How to kill native threads in Android application

I'm using DDMS to monitor threads in my app, and I see that my app has a bunch of native threads as shown in follow picture. And time to time, the number of native threads increased as user interact with my app, which cause my app sometime does not serve as I expect. Is there anyway to kill these native threads?
There is no such thing as a "native thread" on Android, although some people might use that to refer to threads that are not attached to the VM (which would also make them invisible to DDMS). The threads happen to be executing (or waiting) in native code at the time you did a thread dump, but may spend most of their time executing bytecode. (A list of Dalvik thread states is available here.)
The names of the threads suggests that they were created without being given an explicit name. The one thread with a name, NsdManager probably exists because you're using NsdManager, which "responses to requests from an application are on listener callbacks on a seperate thread" [sic].
It's possible that you can glean some useful information from a stack trace. In DDMS, double-click the thread to get a backtrace. On a rooted device, you can kill -3 <pid> to get a full dump, including native stack frames.
Killing arbitrary threads is not allowed, as they might be holding locks or other resources. If you can determine what is starting them, and that they are unnecessary, you can prevent them from being started in the first place.

Android native code fork() has issues with IPC/Binder

I have an Android native Server app compiled as Platform privileged module that forks itself. This module also uses Android services, like SurfaceFlinger. I need to fork to have one sandboxed process per client.
Fork() works fine and the parent process has no issue at all. But in the child process, when I try to access any Android service/resource I get:
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr xxxxxxxx ... ...
/system/lib/libbinder.so (android::Parcel::ipcSetDataReference
...
/system/lib/libbinder.so (android::BpBinder::transact
NativeCrashListener( 1203): Couldn't find ProcessRecord for pid XXXX
This happens even when I try to create a NEW client, thus, not using any previous created reference.
NativeCrashListener doesn't know about my child process, thus, maybe ActivityManager also doesn't.
I looked at the Zygote code but have not found anything helpful there. I'm probably missing some step or calling some function on the child process. Any ideas ??? =)
You can't create a new Binder process this way.
The problem is that fork() only clones the current thread, not all threads. In the new process, the Binder IPC code will expect the Binder helper threads to be running, but none of them will be. You need to fork() and then exec().
The zygote process avoids this issue by having only one thread running when fork() is called. It deliberately defers initialization of the Binder code to the child process. (In the current implementation, it actually has a couple of threads running in Dalvik, but the internal fork handling stops and restarts those threads on every fork).
fadden is right, fork() cannot be used to create a new process that uses Android APIs reliably. The best you can do with it is exec() to run a standalone command-line program, everything else is likely to not work as you expect.
However, the platform supports sandboxed processes, in the form of isolated service processes. See http://developer.android.com/guide/topics/manifest/service-element.html#isolated for more details. In essence, this runs your service in a special process under a random UID that has no permissions.
For the record, this is what Chrome on Android uses to isolate 'tabs' into sandboxed 'renderer processes'.

libDispatch serving main queue without dispatch_main on Android

I am using libDispatch (GCD) opensource on Android platform.
So, most of the complex time consuming tasks are being done through NDK (where i am using libDispatch).
For some calls, I am using dispatch_async(get_main_queue)...This is where the problem is coming...
I am able to run tasks in the concurrent queues but not on main queue.
Since this requires dispatch_main() to be called which we cannot do on here as Java thread will be blocked in that case.
So, is it possible to run the Java UI on some secondary thread and hook the dispatch_main() to serve the dispatch_main_queue here?
OR : Do I need to keep serving the main_queue from JAva main UI thread through JNI ?
Look into _dispatch_main_queue_callback_4CF which is the function you can call to drain the main queue. It will return like a normal sensible function after executing the queued operations, instead of killing the thread like dispatch_main.
Note that you'll need to call _dispatch_main_queue_callback_4CF on a regular basis from your Java UI thread, possibly each iteration. The official Cocoa implementation uses _dispatch_queue_wakeup_main() which uses mach messages to kick the main thread out of any sleep states so it can guarantee the callback function is called quickly, but you'd have to do some work to enable that and build your own libDispatch port. In reality on Android I don't think the main UI thread is ever put to sleep while your app is active so it shouldn't be an issue.
There is a ticket open on the libDispatch site at https://libdispatch.macosforge.org/trac/ticket/38 to make _dispatch_main_queue_callback_4CF a public function. The ticket is marked "Accepted" but no word on if/when that will happen.

Understanding Android: Zygote and DalvikVM

I am trying to understand how Android launches applications. The question is how (and why) does the Zygote fork a new Dalvik VM? I do not understand why it is not possible to run multiple applications in the same Dalvik VM.
Q. how does zygote exactly fork Dalvik VM?
Short Answer:
The Zygote process cold boots a Java VM on system start up. It then listens to a socket for incoming commands. Other processes (e.g. ActivityManagerService) write commands to this socket whenever a new process is needed for an application. These commands are read by the Zygote process which calls fork() as necessary. Child processes get a pre-warmed VM in which to run. This is how Zygote forks the Dalvik VM.
Long answer: After the kernel is loaded, init.rc is parsed and native services are started. Then /system/bin/app_process) is run. This eventually calls AndroidRuntime.start(), passing it the parameters com.android.internal.os.ZygoteInit and start-system-server.
The AndroidRuntime.start() starts a Java VM then calls ZygoteInit.main(), passing it the parameter start-system-server.
ZygoteInit.main() registers the Zygote socket (which the Zygote process listens to for incoming commands, and on receiving new command, spawns a new process as requested). It then preloads a lot of classes (as listed in frameworks/base/preloaded-classes, over 4500 in Android 8.0) and all the system-wide resources like drawables, xmls, etc. Then it calls startSystemServer() which forks a new process for com.android.server.SystemServer. This fork is special and is not done in the same manner as the usual forks the Zygote performs on behalf of requesting processes.
After SystemServer is forked the runSelectLoopMode() function is called. This is a while(true) loop which establishes a ZygoteConnection with the Zygote socket and waits for commands on it. When a command is received, ZygoteConnection.runOnce() is called.
ZygoteConnection.runOnce() then calls Zygote.forkAndSpecialize() which then calls a native function to do the actual fork. Thus, like in the case of SystemServer, a child process is created which inherits a pre-warmed Dalvik VM for itself.
Q. why it is not possible to run multiple applications in the same
Dalvik VM?
This is a design decision as far as I know. The Android guys just decided to fork a new VM per process for security via sandboxing.
No. Dalvik doesn't span processes.
However, the Binder IPC mechanism can do a very convincing job of making objects appear to migrate to a different process and its Dalvik instance. Also, the memory management is very good about sharing read-only pages across all processes that need them. The Dalvik process hosting a typical app is forked off of zygote with all the common android libraries already mapped, so new unique copies don't have to be opened.
Source: Do apps using multiple processes share a Dalvik instance?
Also check these links:
http://davidehringer.com/software/android/The_Dalvik_Virtual_Machine.pdf
http://commonsware.com/blog/Articles/what-is-dalvik.html
Zygote is also used to share the system drawables with all the apps.
This allows the system to load the bitmaps for buttons only once for
instance.
Just to add one more point to answers above when zygote does a fork on receiving a command it uses copy-on-write technique. Memory is copied only when the new process tries to modify it.
Also the core libraries that zygote loads on startup are read only and cannot be modified. So they are not copied over but shared with new forked processes.
All of these led to quick startup and less memory footprint.
Zygote isn't really bound up with Dalvik, it's just an init process. Zygote is the method Android uses to start apps. Rather than having to start each new process from scratch, loading the whole system and the Android framework afresh each time you want to start an app, it does that process once, and then stops at that point, before Zygote has done anything app-specific. Then, when you want to start an app, the Zygote process forks, and the child process continues where it left off, loading the app itself into the VM.

Possible states for native threads on Android?

What are all the possible thread states during execution for native (C/C++) threads on an Android device? Are they the same as the Java Thread States? Are they Linux threads? POSIX threads?
Not required, but bonus points for providing examples of what can cause a thread to enter each state.
Edit: As requested, here's the motivation:
I'm designing the interface for a sampling profiler that works with native C/C++ code on Android. The profiler reports will show thread states over time. I need to know what all the states are in order to a) know how many distinct states I will need to possibly visually differentiate, and b) design a color scheme that visually differentiates and groups the desirable states versus the undesirable states.
I've been told that native threads on Android are just lightweight processes. This agrees with what I've found for Linux in general. Quoting this wiki page:
A process (which includes a thread) on a Linux machine can be in any of the following states:
TASK_RUNNING - The process is either executing on a CPU or waiting to be executed.
TASK_INTERRUPTIBLE - The process is suspended (sleeping) until some condition becomes true. Raising a hardware interrupt, releasing a system resource the process is waiting for, or delivering a signal are examples of conditions that might wake up the process (put its state back to TASK_RUNNING). Typically blocking IO calls (disk/network) will result in the task being marked as TASK_INTERRUPTIBLE. As soon as the data it is waiting on is ready to be read an interrupt is raised by the device and the interrupt handler changes the state of the task to TASK_INTERRUPTIBLE. Also processes in idle mode (ie not performing any task) should be in this state.
TASK_UNINTERRUPTIBLE - Like TASK_INTERRUPTIBLE, except that delivering a signal to the sleeping process leaves its state unchanged. This process state is seldom used. It is valuable, however, under certain specific conditions in which a process must wait until a given event occurs without being interrupted. Ideally not too many tasks will be in this state.
For instance, this state may be used when a process opens a device file and the corresponding device driver starts probing for a corresponding hardware device. The device driver must not be interrupted until the probing is complete, or the hardware device could be left in an unpredictable state.
Atomic write operations may require a task to be marked as UNINTERRUPTIBLE
NFS access sometimes results in access processes being marked as UNINTERRUPTIBLE
reads/writes from/to disk can be marked thus for a fraction of a second
I/O following a page fault marks a process UNINTERRUPTIBLE
I/O to the same disk that is being accessed for page faults can result in a process marked as UNINTERRUPTIBLE
Programmers may mark a task as UNINTERRUPTIBLE instead of using INTERRUPTIBLE
TASK_STOPPED - Process execution has been stopped; the process enters this state after receiving a SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU signal.
TASK_TRACED - Process execution has been stopped by a debugger.
EXIT_ZOMBIE - Process execution is terminated, but the parent process has not yet issued a wait4() or waitpid() system call. The OS will not clear zombie processes until the parent issues a wait()-like call.
EXIT_DEAD - The final state: the process is being removed by the system because the parent process has just issued a wait4() or waitpid() system call for it. Changing its state from EXIT_ZOMBIE to EXIT_DEAD avoids race conditions due to other threads of execution that execute wait()-like calls on the same process.
Edit: And yet the Dalvik VM Debug Monitor provides different states. From its documentation:
"thread state" must be one of:
1 - running (now executing or ready to do so)
2 - sleeping (in Thread.sleep())
3 - monitor (blocked on a monitor lock)
4 - waiting (in Object.wait())
5 - initializing
6 - starting
7 - native (executing native code)
8 - vmwait (waiting on a VM resource)
"suspended" [a separate flag in the data structure] will be 0 if the thread is running, 1 if not.
If you design a system app that has to work with threads in even more advanced way than usual app, I'd first start by examining what API is available on Android to access threads.
The answer is pthread = POSIX threads, with pthread.h header file, implemented in Bionic C library. So you have starting point for knowing what you can achieve.
Another thing is that Android doesn't implement full pthread interface, only subset needed for Android to run.
More on threads + Bionic here, and how they interact with Java and VM is described here. Also I feel that thread is actually a process, as my code uses setpriority(PRIO_PROCESS, gettid(), pr); to set new thread's priority - I don't recall where I got this info, but this works.
I assume that thread may be in running, finished or blocked (e.g. waiting for mutex) state, but that's my a bit limited knowledge since I never needed other thread state.
Now question is if your app can actually retrieve these states using available API in NDK, and if there're more states, if your users would be really interested to know.
Anyway, you may start by displaying possibly incomplete states of threads, and if your users really care, you'd learn about another states from users' feedback and requests.
Google:
Thread.State BLOCKED The thread is blocked and waiting for a lock.
Thread.State NEW The thread has been created, but has never been started.
Thread.State RUNNABLE The thread may be run.
Thread.State TERMINATED The thread has been terminated.
Thread.State TIMED_WAITING The thread is waiting for a specified amount of time.
Thread.State WAITING The thread is waiting.
These states are not very well explained - I don't see the difference between BLOCKED and WAITING, for example.
Interestingly, there is no 'RUNNING' state - do these devices ever do anything?

Categories

Resources