Android Native Code Stack vs Dalvik VM / ART Stack - android

Android apps can execute C/C++ code using the Android NDK. All Android apps also run on the Android VM (i.e. Dalvik/ART).
My question is, does native code in Android apps use the same stack/heap as the Android VM?
i.e. In native code, we can create local variables and also variables via malloc/new, and these will be stored on the stack or heap respectively. But also my understanding is that the Android VM will create objects of it's own for bookkeeping. So does the native code and Android VM share the same stack/heap in memory?

The managed JVM heap and the native heap are separate, but they are not completely isolated. Under the hood, JVM uses the same system calls, and via JNI, you can access java primitive arrays' memory.
As for stack, JVM and C share it per thread. But not all native threads are attached to JVM.

Related

Does the c++ apps build for android run on top of JVM of on the Kernal

In android does the application built with c++ (and packages in apps Like Termux) run on top of the Dalvik JVM or directly communicate with the Linux Kernal
This is explained partly in the Concepts section of the Android NDK documentation.
In brief: every Android user application needs to run the Android event loop in some capacity to receive events, participate in the application lifecycle, and display stuff on the screen.
What people call "native" c++ applications are actually running a "hollow" Java Android application/activity on top of ART (the Android "Java" runtime). The native part is expected to do everything that you get for free from normal Java-based activities: pump events and update the screen regularly.
Now, to answer your final question: for some aspects they can use the Android kernel directly. However, this is a very limited set of operations and more interesting operations either require some of the native APIs (which use an RPC mechanism called Binder to talk to system services) or use JNI to talk to a Java implementation (that in turn probably still uses Binder).

Android JNI under the hood

I cannot find any references to a detailed explanation about how JNI works on Android in detail, so:
Since every Android application runs in its own process, with its own instance of the Dalvik/ART virtual machine, I think that the native code will be executed in the same process, am I right?
I read that when the VM invokes a function, it passes a JNIEnv pointer, a jobject pointer, and any Java arguments declared by the Java method.
But how is this made at assembly level (under the hood)?
I read that you can instantiate objects, call methods, and so on, like Reflection, using the functions provided by the JNIEnv. Therefore, my question is: have I a "direct" memory access to the VM or I have always to use the JNIEnv's functions?
The Android JVM is under Apache license, so the best detailed and precise description can be found in the form of source code. Note that there are two different JVMs: dalvik and art. Under the hood they are very different, to the extent that a user of JNI may consider special adaptations.
the native code will be executed in the same process
Exactly. Note that an Android app can run in more than one process, and also it can spawn child processes (normal Unix behavior). But JNI is not IPC.
how is this made at assembly level?
More or less, this is described in a related
question: What does a JVM have to do when calling a native method?
have I a "direct" memory access to the VM?
Yes, you have. There is no security barrier between your C code and the JVM. You can reverse engineer the data structures, and do whatever you like. The exact implementations of the JVM not only depend on the Android version, but may be modified without notice by the vendor, as long as the public API of the JVM (including JNI) is compatible. The chances that you will do something useful with direct memory access to JVM are minimal, but the risk that it will crash is very high.
Note that this is not a security issue: your C code is running in a separate process (with your Java code), and is subject to the same permissions restrictions as the Java code. It has no access to the private memory of other apps or procsses. Whatever you change in your instance of JVM will not effect VM that runs other apps.

Does Dalvik VM talk to HAL/kernel layer via Bionic Libc?

In the given android stack,
excluding applications written using NDK kit at LIBRARIES layer,
I learnt that, Any app written at APPLICATIONS layer must run in their own processes, inside their own Dalvik VM instance, as shown below:
As per the process stack above, I see that Dalvik runtime is talking to HAL/kernel layer via bionic Libc library.
My question:
Can't Dalvik VM access HAL/Kernel layer without using bionic Libc library interface?
i see some confusion in you when it comes to C Language.
after all bionic is just standard C library for android.
first of all, your answer is NO.
although bionic libC is not below Dalvik in their diagram, the fact is that Dalvik uses libC helper functions to perform some tasks that are considered as operating system services.
like:
string handling, mathematical computations, input/output processing, memory allocation and several other operating system services.

How to take heap snapshot of Xamarin.Android's Mono VM?

Background: I am trying to track down a memory leak in a Xamarin.Android app. Using DDMS and Eclipse Memory Profiler, I am able to see which objects are alive. When trying to track what is holding them alive (GC Root), I only see "Native stack" (of course).
How can I take a heap snapshot of the MONO VM? So I can later use it with i.e. heapshot tool?
Or are there ANY OTHER TECHNIQUES I can use to find what is holding an object alive in Xamarin.Android's .NET part? Is it possible to do something from within the program?
How can I take a heap snapshot of the MONO VM? So I can later use it with i.e. heapshot tool?
It is now possible to get heap snapshots of the Mono VM (tested with Xamarin.Android 4.8.2 beta; may apply to prior releases, your mileage may vary). It's a four step process:
Enable heapshot logging:
adb shell setprop debug.mono.profile log:heapshot
Start your app. (If your app was already running before (1), kill and restart it.)
Use your app.
Grab the profile data for your app:
adb pull /data/data/#PACKAGE_NAME#/files/.__override__/profile.mlpd
#PACKAGE_NAME# is the package name of your application, e.g. if your package is FooBar.FooBar-Signed.apk, then #PACKAGE_NAME# will be FooBar.FooBar.
Analyze the data:
mprof-report profile.mlpd
mprof-report is included with Mono.
Note: profile.mlpd is only updated when a GC occurs, so you may want to call GC.Collect() at some "well known" point to ensure that profile.mlpd is regularly updated .
I have been having troubles with Xamarin Android memory profiling, and have used a few tricks:
On the Dalvik side I have used Android Monitor to dump a heap snapshot and then opening it with JProfiler or Eclipse MAT. This standard Android.
A large portion of my code is shared (70-80%) and to verify this I have built a simple WinForms application to drive the shared API. This way I can use .Net Memory Profiler (or ANTS if you would prefer) as well as dotTrace for performance. I could easily pick quite a few
issues this way.
By using the solution explained by #jnop above I could open the profile.mldp in Mono's HeapShot tool and get a visual tool instead of the mprof-report textual output.
By the way used should vote for better profilers:
http://xamarin.uservoice.com/forums/144858-xamarin-suggestions/suggestions/3229534-add-memory-and-performance-profiler

Quick Question Regarding Android Programming

Not really an immediate source code question per se....but Im looking into doing some casual Android Programming, nothing heavy.
But it seems to use alot of XML and Java......what I wonder though is why is it that android is written mostly in C and XML (along with C++ and Java) with it being closely related to the Linux OS......but why is the "main" language for programming in android Java?
Just out of curiosity of course.
The "main" language, as you called it, is Java. You can use C/C++ via the NDK, but you won't need it unless you are doing some special stuff. If you wonder when you would need to use C/C++, take a look at the official documentation:
When to Develop in Native Code
The NDK will not benefit most applications. As a developer, you need to balance its benefits against its drawbacks; notably, using native code does not result in an automatic performance increase, but always increases application complexity. In general, you should only use native code if it is essential to your application, not just because you prefer to program in C/C++.
Typical good candidates for the NDK are self-contained, CPU-intensive operations that don't allocate much memory, such as signal processing, physics simulation, and so on. Simply re-coding a method to run in C usually does not result in a large performance increase. When examining whether or not you should develop in native code, think about your requirements and see if the Android framework APIs provide the functionality that you need. The NDK can, however, can be an effective way to reuse a large corpus of existing C/C++ code.
The Android framework provides two ways to use native code:
Write your application using the Android framework and use JNI to access the APIs provided by the Android NDK. This technique allows you to take advantage of the convenience of the Android framework, but still allows you to write native code when necessary. You can install applications that use native code through the JNI on devices that run Android 1.5 or later.
Write a native activity, which allows you to implement the lifecycle callbacks in native code. The Android SDK provides the NativeActivity class, which is a convenience class that notifies your native code of any activity lifecycle callbacks (onCreate(), onPause(), onResume(), etc). You can implement the callbacks in your native code to handle these events when they occur. Applications that use native activities must be run on Android 2.3 (API Level 9) or
You cannot access features such as Services and Content Providers natively, so if you want to use them or any other framework API, you can still write JNI code to do so.
I am just guessing but Java is a bit easier to program than C/C++ so its more attractive to new programmer which is also good for the platform success itself.
Another reason might be that an application written in java runs in a separate VM so it can be much easier controlled by android. If a vm is not responding the main OS can just kill it and the phone is still responding.
Suaron... From a stability point of view Java apps should be less likely to take down the device. So Java || C# || C++/CLI safer than C++ vs C vs Assembly. To this end the API is in Java and so most Apps are in Java.
On the other hand C/C++ gets closer to the hardware and is more appropriate for writing libraries that interact with hardware. It is much easier to shoot yourself in the foot with C++.
JAL

Categories

Resources