写一写前两天用android ndk profiler 分析本地代码的过程,在此记录一下,防止以后忘记
步骤:
2、更改Android.mk, 加载android ndk profiler模块。
其实这个步骤的详细过程官网已经有了,基本按官网的说明来做就可以了:http://code.google.com/p/android-ndk-profiler/wiki/Usage
# compile with profiling
LOCAL_CFLAGS := -pg
LOCAL_STATIC_LIBRARIES := android-ndk-profiler
# at the end of Android.mk
$(call import-module,android-ndk-profiler)
看我的android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# compile with profiling
LOCAL_CFLAGS := -pg
LOCAL_STATIC_LIBRARIES := android-ndk-profiler
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
# at the end of Android.mk
$(call import-module,android-ndk-profiler)
3、3 在启动和结束函数里,加入监视代码。默认会产生sdcard/gmon.out文件。所以你需要在sdcard上的写权限,修改AndroidManifest.xml,加上:
4、修改本地代码,在本地代码需要调试的起始位置和结束位置加上监视函数:
/* in the start-up code */
monstartup("your_lib.so");
/* in the onPause or shutdown code */
moncleanup();
我的例子的代码:
#include
#include
#include
#include
#include
jstring Java_com_wxg_ndkdemo_MainActivity_stringFromJNI(JNIEnv *env ,jobject thiz)
{
int i ;
setenv("CPUPROFILE_FREQUENCY", "500", 1); /* Change to 500 interrupts per second */
monstartup("libhello-jni.so");
test();
//setenv("CPUPROFILE", "/sdcard/gmon.out", 1);
moncleanup();
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
jint add()
{
int i=10000,j=0;
for(i=0;i<10000;i++)
{
for(j=0;j<10000;j++)
{
i*j;
}
}
return i+j;
}
jint test()
{
add();
//int i;
//char buffer[] = "Hello world/n";
//printf("Buffer before memset: %s/n", buffer);
//memset(buffer, '*', strlen(buffer) );
//printf("Buffer after memset: %s/n", buffer);
//
//FILE *fp = fopen("/sdcard/a.txt","at");
//
//fprintf(fp,"%s\n",buffer);
//
//for(i=0;i<100000;i++)
//{
//char ch[30];
//sprintf(ch,"the number is %d\n",i);
//char str[30];
//memcpy(str,ch,strlen(ch));
//fputs(ch,fp);
fprintf(fp,"%s\n",ch);
//}
//
//fclose(fp);
int i,j;
double s = 0,temp=1.0;
for(i=1;i<=5000000;i++)
{
s += sqrt(temp);
temp = s;
}
return 0;
}
5、使用ndk-build编译本地代码
ubuntu@ubuntu:~/workspace/NDKDemo$ ndk-build NDK_MODULE_PATH=~/android/
Install : libhello-jni.so => libs/armeabi/libhello-jni.so
其中
NDK_MODULE_PATH=~/android/
指向的是包含android_ndk_profiler文件夹的目录,看我的
ubuntu@ubuntu:~/android$ ls android-ndk*
android-ndk-profiler:
Android.mk armeabi armeabi-v7a prof.h
android-ndk-r8e:
build documentation.html ndk-build ndk-gdb ndk-gdb.py ndk-stack platforms README.TXT samples tests
docs GNUmakefile ndk-build.cmd ndk-gdb-py ndk-gdb-py.cmd ndk-which prebuilt RELEASE.TXT sources toolchains
6、运行程序,最后查看结果
使用gprof命令产生结果,需要先用adb pull命令将gmon.out文件拷贝到自己的PC上
先进入你android的NDK项目的obj目录下的objs下的子目录下:
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ls
hello-jni.o hello-jni.o.d
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ adb pull /sdcard/gmon.out
355 KB/s (16463 bytes in 0.045s)
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ls
gmon.out hello-jni.o hello-jni.o.d
最后使用NDK的gprof查看结果
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ~/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gprof hello-jni.o
来源:oschina
链接:https://my.oschina.net/u/561492/blog/153416