Is there a "live" memory profiler tool (similar to Instruments in XCode) for Android? Most searches for memory profiling, leads me to Memory Analyzer Tool (which is great), but I would very much appreciate a tool which can dynamically show me which classes consume (and release) memory during the life-cycle of my application, as it is executing.
Note: I am not looking for a memory profiling tool for Android (Memory Analyzer Tools works very well for me). All the methods/tools I have encountered, take a snapshot of the heap and save it to a file. I am looking for a tool which provides a live counter/update on what portion of the heap is being used by various objects, and this is updated on a second/sub-second basis. It is possible that this might not be possible with Android. However, I have not found a definite answer one way or another.
Take a look at this video here at around 35mins in they show how to profile your app, not sure if you can do it 'live' tho.
More information from this post on milk.com:
Haven't tried this since android 1.6 and not sure if you could do it live but you used to be able to generate heap data by:
Get a command shell on the device:
$ adb shell
You can verify that you're running as root with the id command. The response should look like uid=0(root) gid=0(root). If not, type su and try again. If su fails, you're out of luck.
Next, ensure the target directory exists:
# mkdir /data/misc
# chmod 777 /data/misc
Use ps or DDMS to determine the process ID of your application, then send a SIGUSR1 to the target process:
# kill -10 <pid>
The signal causes a GC, followed by the heap dump (to be completely accurate, they actually happen concurrently, but the results in the heap dump reflect the post-GC state). This can take a couple of seconds, so you have to watch for the GC log message to know when it's complete.
Next:
# ls /data/misc/heap-dump*
# exit
Use ls to check the file names, then exit to quit the device command shell.
You should see two output files, named /data/misc/heap-dump-BLAH-BLAH.hprof and .hprof-head, where BLAH is a runtime-generated value that ensures the filename is unique. Pull them off of the device and remove the device-side copy:
$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof tail.hprof
$ adb pull /data/misc/heap-dump-BLAH-BLAH.hprof-head head.hprof
$ adb shell rm /data/misc/heap-dump-BLAH-BLAH.hprof /data/misc/heap-dump-BLAH-BLAH.hprof-head
Merge them together and remove the intermediates:
$ cat head.hprof tail.hprof > dump.hprof
$ rm head.hprof tail.hprof
You now have the hprof dump in dump.hprof.
The data file format was augmented slightly from the common hprof format, and due to licensing restrictions the modified hat tool cannot be distributed. A conversion tool, hprof-conv, can be used to strip the Android-specific portions from the output. This tool was first included in 1.5, but will work with older versions of Android.
The converted output should work with any hprof data analyzer, including jhat, which is available for free in the Sun JDK, and Eclipse MAT.
Related
Background: I am working with a Pixel 4, build QQ2A.200501.001.B2, which is Android 10. When I build the kernel from the official sources and flash it, the touchscreen, wlan and other features do not work. I tracked this down to the fact that the kernel modules in /vendor/lib/modules do not get updated, thus the new kernel can't load any of them. I tried flashing both only boot.img and the entire AOSP, same issue, they don't get updated. I can workaround this by manually pushing the kernel modules I built to the device and manually insmoding them in the right order.
So my questions are:
Why don't they get updated in the first place?
How can I update them along with the kernel when I flash?
Alternatively, how can I permanently update them after flashing?
Surely there must be an "official" way to do this? How are the kernel modules normally deployed?
Some notes:
I can't push them to /vendor/lib/modules because I can't remount /vendor writable:
flame:/ # mount -o rw,remount /vendor
'/dev/block/dm-5' is read-only
Disabling dm-verity doesn't seem to help.
I noticed that the AOSP source contains all the modules that are in /vendor/lib/modules, in the same place where it takes the kernel image form (in my case that's device/google/coral-kernel). So naturally, I tried replacing the modules there with the ones I built, but after building and flashing, I see that /vendor/lib/modules still contains the old modules.
The AOSP docs say that boot.img does not contain the ramdisk anymore, it's now in the system partititon. Also, OverlayFS is used and one should use a "vendor overlay" to update files there, if I read it right. However, on my device, there is no product/vendor_overlay directory like the docs say, only product/overlay/. I'm also not sure if this is the right way to tackle this or how I would go about creating such an overlay in my case.
Thanks
Ok. Several questions, several answers:
Why don't they get updated in the first place?
Because they are expected to be in /vendor/lib/modules, and when you recompile a kernel you're only creating the kernel binary which goes into the boot.img.
How can I update them along with the kernel when I flash?
You could compile the modules into the kernel. That makes your kernel a bit bigger, but relieves you from the need to insert these modules.
Alternatively, how can I permanently update them after flashing?
You can indeed modify /vendor like you've tried - but not the DM-verity block device (/dev/block/dm-5 in your case) - the underlying partition (/dev/block/sd?#, something, which you can see if you look at the links from /dev/block/by-name/vendor).
CAVEAT: This will cause dm-verity to fail mounting /vendor unless you correctly disable dm-verity!
Another avenue to try for testing: Linux kernel modules have a strict vermagic requirement (in simpler terms, the module string must match the 'uname -r' of the kernel, to ensure that critical kernel structures have not been modified). If you don't change the kernel magic (VERSION, PATCHLEVEL, SUBLEVEL and EXTRAVERSION from Makefile) (or "fake" them to the original kernel version your device came with) the modules should load.
Alternatively, how can I permanently update them after flashing?
You can use below command to disable verity :
adb root
adb disable-verity
adb shell sync
adb reboot
then push the .ko(s) to /vendor/lib/modules/ :
adb root
adb remount
adb push *.ko /vendor/lib/modules/
adb shell sync
adb reboot
I've compiled Valgrind for ARM using this with minor alterations.
After installing on a phone with the method specified, I get the following error:
# /data/local/Inst/bin/valgrind
valgrind: failed to start tool 'memcheck' for platform 'arm-linux': Permission denied
On closer investigation, it is possible to find what it's trying to do:
# /data/local/Inst/bin/valgrind -d -v
--25068:1:debuglog DebugLog system started by Stage 1, level 1 logging requested
--25068:1:launcher no tool requested, defaulting to 'memcheck'
--25068:1:launcher no client specified, defaulting platform to 'arm-linux'
--25068:1:launcher launching /data/local/Inst/lib/valgrind/memcheck-arm-linux
valgrind: failed to start tool 'memcheck' for platform 'arm-linux': Permission denied
However, the executable is there and has the right permissions:
# ls -l /data/local/Inst/lib/valgrind/memcheck-arm-linux
-rwxrwxrwx root root 9261240 2013-10-28 17:00 memcheck-arm-linux
Furthermore, trying to execute it yields no problem, which eliminates dynamic linking problems as well:
/data/local/Inst/lib/valgrind/memcheck-arm-linux
valgrind: You cannot run '/data/local/Inst/lib/valgrind/memcheck-arm-linux' directly.
valgrind: You should use $prefix/bin/valgrind.
At this point, I'm mostly out of ideas, any help would be greatly appreciated.
I'm aware of this similar post, but I'm sure (based on the output with "-d") the prefix is right.
Potential clue: this worked a few "ROM"-s before, but unfortunately, this current one is the exact same on which it worked previously, with the exact same Valgrind build.
The minor alterations: since the build was done on a 64 bit system, _64 was appended to toolchain paths where appropriate. I can post the full script, but it should be irrelevant. Famous last words, potentially.
I recently ran into the exact same problem.
On my device /data/local/Inst and all of its content is owned by a user named "shell".
Strange enough, when I try to execute valgrind with the root user, I get the above-mentioned error, but as soon as I log in with the unprivileged user, I can run valgrind without any issues.
From the information you posted, I take, that you installed valgrind as the root user, and I assume you also executed it as root.
So here are the steps that got it working for me:
/data/local/Inst is owned by an unprivileged user
Install valgrind with the same unprivileged user
Again, execute valgrind with the same user
Hope this helps.
Normally, this indicates some files (either lib or config files) lack the permission to you. Most likelihood is when you install the Valgrind with root, the umask may exclude the rx for others.
It is easy to solve this by adding the rx permission for others:
find /usr/local -name "*valgrind*" -exec chmod o+rxt {} \;
If you use Valgrind on Android, at least there are three way to solve the problem. (You must root your Android phone first.)
On your PC
cmd
adb shell
$su
#cp /data/local/Inst/bin/valgrind /system/bin/
Note: Remember to chmod. For example chmod 777 valgrind.
On your Android phone
Install an app "Root Explorer". Copy valgrind to /system/bin/ with the app.
Write a shell script
This is a example: Can't run a Java Android program with Valgrind
Chinese Comments:
我本人曾不止一次英语考试不及格。写英文回贴真的很不舒服。不过自我学Android开始,就从http://stackoverflow.com 这里得到过很多帮助。 知恩回报是中华民族的传统美德,所以
就硬首头皮写了这个E文回贴。
I've selected several of the trace tags and when I run the trace (from DDMS) I get the following output:
Unexpected error while collecting system trace. Unable to find trace start marker 'TRACE:':
error opening /sys/kernel/debug/tracing/options/overwrite:
No such file or directory (2)
error openi(cuts off the error here)
indeed there is no debug file in the kernel directory, but which mechanism will generate the necessary path?
It looks like your cellphone is running a boot(kernel) image that does not support systrace.
"error opening /sys/kernel/debug/tracing/options/overwrite: No such file or directory (2)"
This error message means adb daemon (the adb module running on device side) could not find /sys/kernel/debug/tracing/options/overwrite on your device's file system. systrace works over adb and communicates with kernel though sysfs nodes under /sys/kernel/debug/tracing. If these nodes are not exposed on you phone for whatever reason, systrace just will not work.
So you should first get a shell on your device using:
adb shell
Then browse to confirm if /sys exists at all and if /sys/kernel/debug/tracing exists.
If they are there which is extremely unlikely, you have to debug systrace.py to figure out how come systrace think the nodes were not there. Otherwise, you need to flash a different boot image which has systrace support, because sysfs is controlled by kernel(mostly by configurations at compile time) and init.rc , both of which are part of boot image.
Flashing a different boot image might involve unlocking/rooting the device. You probably have to go to fan sites like xdadeveloper for information and image. Another option is to download the source of kernel for your device, compile kernel and make the boot image yourself. Linux is under GPL thus manufacturer of your device is obligated to release the source code of the specialized kernel they use.
-NAM
http://www.willpromo.com
You may need to slightly modify the kernel image(boot.img). The following work find for me, just for your reference.
open terminal and enter: $adb shell
(1) $su (2) $mount -t debugfs none /sys/kernel/debug. Now you should be able to see many directories under /sys/kernel/debug/. (You may cd into /sys/kernel/debug to confirm this)
Enter: $dd if=/dev/block/platform/msm_sdcc.1/by-name/boot of=/sdcard/boot.img to generate the boot.img kernel image from your device.
Use AndroidImageKitchen to unpack the boot.img and find the default.prop within Ramdisk folder. Then change ro.debuggable=0 to ro.debuggable=1. Repack the boot.img and flash boot it to your device.
Once the device boot, under terminal, enter: $adb root and message like: $restarting adbd as root may pop up. Disconnect the USB and connect again.
cd to the systrace folder, e.g. ~/androidSDK/platform-tools/systrace and use:
python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
Now you may able to generate your own systrace files.
Systrace Android tool calls internally a tool called atrace which is and extension of ftrace or strace (Linux tools).
If we connect via the emulator console (ADB shell) to Android Jelly Bean we can execute strace tool but we can not execute ftrace tool (command not installed).
Doing some reseach over the Internet I found that strace is a predecessor of ftrace:
http://crtags.blogspot.de/2012/04/dtrace-ftrace-ltrace-strace-so-many-to.html
Looking to Android Source Code, the most "internal" reference that I found is Trace.h file:
http://androidxref.com/4.1.1/xref/frameworks/native/include/utils/Trace.h
I think that this file is then resolved to a native Linux driver.
However, I'm still unable to know if this implementation driver belongs to strace or ftrace. "Normally", it should be ftrace because it is newer, but in that case I don't know why we can not run ftrace from the emulator. In contrast, strace is completely available from the emulator.
Then, does someone knows if Systrace Android tool uses at a very low level strace or ftrace?
Thank you!
I've follow the instructions found here, related to ftrace,:
http://www.linuxforu.com/2010/11/kernel-tracing-with-ftrace-part-1/
Everything works perfect. I wasn't able to execute ftrace before because interacting and retrieving data is done via logical paths.
To execute ftrace, after correctly configuration (many steps...), inside adb shell:
root#android:# cat /sys/kernel/debug/tracing/trace > mytracefile.txt
atrace makes configuration process easier, so we can access to trace information the following way:
root#android:# atrace -s -w -t 100 > mytracefile.txt
On the other hand, I've found information about executing strace here:
http://www.hokstad.com/5-simple-ways-to-troubleshoot-using-strace
All indicated examples were successfully executed in my environment using adb shell.
Interaction and access to results of both tools are very different.
Now I can say that systrace Android tool is based in atrace which in turn is based in ftrace.
strace is also supported but serves to another purposes and is not related to systrace.
Regards,
I need to run a script that sets cpu_freq .In order to retain the settings after reboot i need to run script which takes care of this issue.I tried to write service in init.rc but the edited part in init.rc disappears on reboot .is there some other way to start script on reboot.thanks
I've found success with magisk. When installed, it adds a directory for boot scripts under /data/adb/service.d, in which you can throw your shell scripts and have them executed by Magisk on boot.
For example, I have the following script:
#!/bin/sh
sleep 15 # to make sure we aren't running in an early stage of the boot process
crond -b -c /data/crontab/
Once created as /data/adb/service.d/start-crond.sh and made executable, it automatically launches crond at boot (provided by Magisk's internal busybox instance).
Use Script Manager.
This link may be helpful:
[ADDON][Xperia S] Generic startup/init.d scripts support for Stock ROM/Kernel
http://forum.xda-developers.com/showthread.php?t=1547238
Although it is for Xperia S, it also works for my ideos. I think the theory behind is quite generic. And if you have installed busybox, you can unzip the downloaded package, read the batch and make some change to the phone by yourself.
If you really want to run your script manually after boot, I prefer scriptme in play market. It's simple and small.