① 如何用adb命令查看android手机具体某个应用的耗电量
运用这些ADB命令可以很直观的查看到你手机上的硬件与软件方面的详细信息。可查看手机系统的具体命令如下:getprop 查看机器的全部信息参数
getprop ro.serialno 查看机器的SN号
getprop ro.carrier 查看机器的CID号
getprop ro.hardware 查看机器板子代号
首先在你的电脑键盘上同时按下 WIN+R ,这时候会弹出一个 运行 窗口。
接着在框中输入 CMD ,并按下 确定 。这时候就会弹出一个命令窗了!
上面所提供的ADB命令也就是在这个窗口下所运行的!先输入 adb shell ,按下回车。然后就可以开始输入上面所提供的命令了!getprop ro.serialno:查看机器的SN号getprop ro.carrier:查看机器的CID号android女用的是传说中三星的M100S,而这里作为示例的是T-Mobile版的G1,所以在这显示的是TMUS。getprop ro.hardware:查看机器板子代号可以看到G1的开发代号叫作trout!getprop ro.bootloader:查看SPL(Hboot)版本号getprop:查看机器的全部信息参数在这能看到你机器的全部的信息参数,从你的硬件信息到所刷的ROM版本信息。
1. 打开终端,进入上述目录,如下图所示:
2. 输入adb shell,打开adb命令行,如下图所示:
3. 查看cpu使用情况:
输入命令:top -m 10 -s cpu(-m显示最大数量,-s 按指定行排序),如下图所示:
参数含义:
PID : progress identification,应用程序ID
S : 进程的状态,其中S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值是负数
#THR : 程序当前所用的线程数
VSS : Virtual Set Size虚拟耗用内存(包含共享库占用的内存)
RSS : Resident Set Size实际使用物理内存(包含共享库占用的内存)
PCY : 前台(fg)和后台(bg)进程
UID : UserIdentification,用户身份ID
Name : 应用程序名称
注意第一列的pid,使用pid值可以查看当前程序的内存使用情况。
4. 查看指定程序内存使用情况:
输入命令: mpsys meminfo 3253,如下图所示:
参数含义:
dalvik : dalvik使用的内存
native : native堆上的内存,指C\C++堆的内存(android 3.0以后bitmap就是放在这儿)
other : 除了dalvik和native的内存,包含C\C++非堆内存······
Pss : 该内存指将共享内存按比例分配到使用了共享内存的进程
allocated : 已使用的内存
free : 空闲的内存
private dirty : 非共享,又不能被换页出去的内存(比如linux系统中为了提高分配内存速度而缓冲的小对象,即使你的进程已经退出,该内存也不会被释放)
share dirty : 共享,但有不能被换页出去的内存
5. 使用ctrl + c,退出adb命令行。
② Android malloc_debug介绍
android 的libc中有友兆弯malloc_debug的hook调用,我们可以使用malloc_debug中的hook函数对内存分配进行跟踪加测。
malloc_debug主要包含的功猜仔能如下:
2) 支持内存边界,可以在申请的内存头部和尾部添加guard,内存越界检查,use after free,内存崩溃检查等。
3) 调用栈跟踪和打印,跟踪内存分配的同时保存内存分配的调用栈,方便内存泄漏检查。
1) 开启malloc_debug
adb shell setprop libc.debug.malloc.program
libc在初始化时会调用MallocInitImpl判断属性来加载debug so,调用InitMallocFunctions替换掉Libc原生的内存分配和释放函数。
除了内存分配和释放,常见如下:
比如在完成注册后,调用FinishInstallHooks,initialize,将finalize注册到process退出时。
1) 内存边界检查好闷
front_guard[=SIZE_BYTES]Enables a small buffer placed before the allocated data.
rear_guard[=SIZE_BYTES] Enables a small buffer placed after the allocated data.
guard[=SIZE_BYTES] Enables both a front guard and a rear guard on all allocations.
主要原理是在分配内存的头部和尾部添加一段数据,作为边界,头部初始化为0xaa,尾部初始化为0xbb。
2)调用栈功能
backtrace[=MAX_FRAMES]
backtrace_enable_on_signal[=MAX_FRAMES]
backtrace_mp_on_exit
backtrace_mp_prefix
backtrace_full
设置保存的调用栈个数,在信号量或者退出时打印调用栈
3) malloc内存默认值
fill_on_alloc[=MAX_FILLED_BYTES] size will be set to 0xeb.
fill_on_free[=MAX_FILLED_BYTES] When an allocation is freed, fill it with 0xef.
fill[=MAX_FILLED_BYTES] This enables both the fill_on_alloc option and the fill_on_free option.
expand_alloc[=EXPAND_BYTES] Add an extra amount to allocate for every allocation.
1) 内存泄漏检测
在shell命令下执行 #setprop libc.debug.malloc.options "backtrace leak_track verbose"
这样开启后在进程退出时会打印leak信息,在发送kill -47时会打印当前内存申请
2) 内存崩溃检查
在shell命令中添加guard #setprop libc.debug.malloc.options "backtrace leak_track verbose guard"
这样会检测内存覆盖等检测
3) verify_pointers 开启可以检测use after free和double free等操作
③ android内存 free和allocated的区别
android:process
定义activity运行所在的进程名称。一般情况下,应用的所有组件都运行在为应用创建的默认的进程中,该默认进程的名称应用包名称一致。通过定义<application>元素的“process”属性可以为所有组件指定一个不同的默认进程。但是任搜颂意组件都可以重写默认进程,以便实现多进程操作。
如果该属性指定名称以“:”开头,则一个新的专属于该应用的进程将会被创建。如果该进程名以小写字母开头,则为该activity提供权限以让其在一个全局的进程中运行。这样会允许多野漏纳个应用的不同组件共用一个进程,以便节省资源。
Android是支持多进程的,每个进程的内存使用限制一般为24MB的内存,所以当完成一些很耗费内存的操作如处理高分辨率图片时,需要单独开一个进程来执行该操作(上面的配置颂没可以用来实现该操作)。即便如此,开发者还是不要随意多开进程来耗费用户的资源。(内存限制,有16MB,24MB, 32MB,很老的机型的内存限制会是16MB,这个具体还要再搜索下资料。。)
另外一些还有一些其他的方式来绕过内存限制,使用更多的资源来完成自己的任务,如下文(有待实践):
How to work around Android’s 24 MB memory limit
The Android framework enforces a per-process 24 MB memory limit. On some older devices, such as the G1, the limit is even lower at 16 MB.
What’s more, the memory used by Bitmaps is included in the limit. For an application manipulating images it is pretty easy to reach this limit and get the process killed with an OOM exception:
E/dalvikvm-heap(12517): 1048576-byte external allocation too large for this process.
E/GraphicsJNI(12517): VM won't let us allocate 1048576 bytes
D/AndroidRuntime(12517): Shutting down VM
W/dalvikvm(12517): threadid=1: thread exiting with uncaught exception (group=0x4001d7f0)
E/AndroidRuntime(12517): FATAL EXCEPTION: main
E/AndroidRuntime(12517): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
This limit is ridiculously low. For a device, like the Nexus One, with 512MB of physical RAM, setting the per-process memory limit for the foreground activity to only 5% of the RAM is a silly mistake. But anyway, that’s how things are and we have to live with it —i.e. find how to work around it.
There are two ways to allocate much more memory than the limit:
One way is to allocate memory from native code. Using the NDK (native development kit) and JNI, it’s possible to allocate memory from the C level (e.g. malloc/free or new/delete), and such allocations are not counted towards the 24 MB limit. It’s true, allocating memory from native code is not as convenient as from Java, but it can be used to store some large amounts of data in RAM (even image data).
Another way, which works well for images, is to use OpenGL textures — the texture memory is not counted towards the limit.
To see how much memory your app has really allocated you can use android.os.Debug.getNativeHeapAllocatedSize().
Using either of the two techniques presented above, on a Nexus One, I could easily allocate 300MB for a single foreground process — more than 10 times the default 24 MB limit.
④ 如何在Android用FFmpeg+SDL2.0解码图像线程
创建一个VideoPicture结构体用来保存解码出来的图像。
/*
*SDL_Lesson.c
*
*Createdon:Aug12,2014
*Author:clarck
*/
#include<jni.h>
#include<android/native_window_jni.h>
#include"SDL.h"
#include"SDL_thread.h"
#include"SDL_events.h"
#include"../include/logger.h"
#include"../ffmpeg/include/libavcodec/avcodec.h"
#include"../ffmpeg/include/libavformat/avformat.h"
#include"../ffmpeg/include/libavutil/pixfmt.h"
#include"../ffmpeg/include/libswscale/swscale.h"
#include"../ffmpeg/include/libswresample/swresample.h"
#defineSDL_AUDIO_BUFFER_SIZE1024
#defineMAX_AUDIO_SIZE(5*16*1024)
#defineMAX_VIDEO_SIZE(5*256*1024)
#defineFF_ALLOC_EVENT(SDL_USEREVENT)
#defineFF_REFRESH_EVENT(SDL_USEREVENT+1)
#defineFF_QUIT_EVENT(SDL_USEREVENT+2)
#defineVIDEO_PICTURE_QUEUE_SIZE1
#defineAVCODEC_MAX_AUDIO_FRAME_SIZE192000//1secondof48khz32bitaudio
typedefstructPacketQueue{
散羡稿AVPacketList*first_pkt,*last_pkt;
intnb_packets;
intsize;
SDL_mutex*mutex;
SDL_cond*cond;
}PacketQueue;
typedefstructVideoPicture{
SDL_Window*screen;
SDL_Renderer*renderer;
SDL_Texture*bmp;
AVFrame*rawdata;
派伏intwidth,height;/*sourceheight&width*/
intallocated;
}VideoPicture;
typedefstructVideoState{
charfilename[1024];
AVFormatContext*ic;
intvideoStream,audioStream;
AVStream*audio_st;
AVFrame*audio_frame;
PacketQueueaudioq;
unsignedintaudio_buf_size;
unsignedintaudio_buf_index;
AVPacketaudio_pkt;
uint8_t*audio_pkt_data;
intaudio_pkt_size;
uint8_t*audio_buf;
DECLARE_ALIGNED(16,uint8_t,audio_buf2)[AVCODEC_MAX_AUDIO_FRAME_SIZE*4];
enumAVSampleFormataudio_src_fmt;
enumAVSampleFormataudio_tgt_fmt;
冲孝intaudio_src_channels;
intaudio_tgt_channels;
int64_taudio_src_channel_layout;
int64_taudio_tgt_channel_layout;
intaudio_src_freq;
intaudio_tgt_freq;
structSwrContext*swr_ctx;
AVStream*video_st;
PacketQueuevideoq;
VideoPicturepictq[VIDEO_PICTURE_QUEUE_SIZE];
intpictq_size,pictq_rindex,pictq_windex;
SDL_mutex*pictq_mutex;
SDL_cond*pictq_cond;
SDL_Thread*parse_tid;
SDL_Thread*audio_tid;
SDL_Thread*video_tid;
AVIOContext*io_ctx;
structSwsContext*sws_ctx;
intquit;
}VideoState;
VideoState*global_video_state;
如果我的回答没能帮助您,请继续追问。
转载,仅供参考。
⑤ 如何分析解决Android ANR
一:什么是ANR
ANR:Application Not Responding,即应用无响应
二:ANR的类型
ANR一般有三种类型:
1:KeyDispatchTimeout(5 seconds) --主要类型
按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds)
BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) --小概率类型
Service在特定的时间内无法处理完橡兄雹成
三:KeyDispatchTimeout
Akey or touch event was not dispatched within the specified time(按键或触摸事件在特定时间内无响应)
具体的超时时间的定义在framework下的
ActivityManagerService.java
//How long we wait until we timeout on key dispatching.
staticfinal int KEY_DISPATCHING_TIMEOUT = 5*1000
四:为什么会超时呢?
超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被梁帆某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成
五尘败:如何避免KeyDispatchTimeout
1:UI线程尽量只做跟UI相关的工作
2:耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理
3:尽量用Handler来处理UIthread和别的thread之间的交互
六:UI线程
说了那么多的UI线程,那么哪些属于UI线程呢?
UI线程主要包括如下:
Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick(),etc
AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel,etc
Mainthread handler: handleMessage(), post*(runnable r), etc
other
七:如何去分析ANR
先看个LOG:
04-01 13:12:11.572 I/InputDispatcher( 220): Application is not responding:Window{2b263310com.android.email/com.android.email.activity.SplitScreenActivitypaused=false}. 5009.8ms since event, 5009.5ms since waitstarted
04-0113:12:11.572 I/WindowManager( 220): Input event dispatching timedout sending tocom.android.email/com.android.email.activity.SplitScreenActivity
04-01 13:12:14.123 I/Process( 220): Sending signal. PID: 21404 SIG: 3---发生ANR的时间和生成trace.txt的时间
04-01 13:12:14.123 I/dalvikvm(21404):threadid=4: reacting to signal 3
……
04-0113:12:15.872 E/ActivityManager( 220): ANR in com.android.email(com.android.email/.activity.SplitScreenActivity)
04-0113:12:15.872 E/ActivityManager( 220): Reason:keyDispatchingTimedOut
04-0113:12:15.872 E/ActivityManager( 220): Load: 8.68 / 8.37 / 8.53
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 4361ms to 699ms ago ----CPU在ANR发生前的使用情况
04-0113:12:15.872 E/ActivityManager( 220): 5.5%21404/com.android.email: 1.3% user + 4.1% kernel / faults: 10 minor
04-0113:12:15.872 E/ActivityManager( 220): 4.3%220/system_server: 2.7% user + 1.5% kernel / faults: 11 minor 2 major
04-0113:12:15.872 E/ActivityManager( 220): 0.9%52/spi_qsd.0: 0% user + 0.9% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%65/irq/170-cyttsp-: 0% user + 0.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 0.5%296/com.android.systemui: 0.5% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait
04-0113:12:15.872 E/ActivityManager( 220): CPUusage from 3697ms to 4223ms later:-- ANR后CPU的使用量
04-0113:12:15.872 E/ActivityManager( 220): 25%21404/com.android.email: 25% user + 0% kernel / faults: 191 minor
04-0113:12:15.872 E/ActivityManager( 220): 16% 21603/__eas(par.hakan: 16% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 7.2% 21406/GC: 7.2% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 1.8% 21409/Compiler: 1.8% user + 0% kernel
04-0113:12:15.872 E/ActivityManager( 220): 5.5%220/system_server: 0% user + 5.5% kernel / faults: 1 minor
04-0113:12:15.872 E/ActivityManager( 220): 5.5% 263/InputDispatcher: 0% user + 5.5% kernel
04-0113:12:15.872 E/ActivityManager( 220): 32%TOTAL: 28% user + 3.7% kernel
从LOG可以看出ANR的类型,CPU的使用情况,如果CPU使用量接近100%,说明当前设备很忙,有可能是CPU饥饿导致了ANR
如果CPU使用量很少,说明主线程被BLOCK了
如果IOwait很高,说明ANR有可能是主线程在进行I/O操作造成的
除了看LOG,解决ANR还得需要trace.txt文件,
如何获取呢?可以用如下命令获取
$chmod 777 /data/anr
$rm /data/anr/traces.txt
$ps
$kill -3 PID
adbpull data/anr/traces.txt ./mytraces.txt
从trace.txt文件,看到最多的是如下的信息:
-----pid 21404 at 2011-04-01 13:12:14 -----
Cmdline: com.android.email
DALVIK THREADS:
(mutexes: tll=0tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1NATIVE
| group="main" sCount=1 dsCount=0obj=0x2aad2248 self=0xcf70
| sysTid=21404 nice=0 sched=0/0cgrp=[fopen-error:2] handle=1876218976
atandroid.os.MessageQueue.nativePollOnce(Native Method)
atandroid.os.MessageQueue.next(MessageQueue.java:119)
atandroid.os.Looper.loop(Looper.java:110)
at android.app.ActivityThread.main(ActivityThread.java:3688)
at java.lang.reflect.Method.invokeNative(Native Method)
atjava.lang.reflect.Method.invoke(Method.java:507)
atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:624)
at dalvik.system.NativeStart.main(Native Method)
说明主线程在等待下条消息进入消息队列
八:Thread状态
ThreadState (defined at “dalvik/vm/thread.h “)
THREAD_UNDEFINED = -1, /* makes enum compatible with int32_t */
THREAD_ZOMBIE = 0, /* TERMINATED */
THREAD_RUNNING = 1, /* RUNNABLE or running now */
THREAD_TIMED_WAIT = 2, /* TIMED_WAITING in Object.wait() */
THREAD_MONITOR = 3, /* BLOCKED on a monitor */
THREAD_WAIT = 4, /* WAITING in Object.wait() */
THREAD_INITIALIZING= 5, /* allocated, not yet running */
THREAD_STARTING = 6, /* started, not yet on thread list */
THREAD_NATIVE = 7, /* off in a JNI native method */
THREAD_VMWAIT = 8, /* waiting on a VM resource */
THREAD_SUSPENDED = 9, /* suspended, usually by GC or debugger */
九:如何调查并解决ANR
1:首先分析log
2: 从trace.txt文件查看调用stack.
3: 看代码
4:仔细查看ANR的成因(iowait?block?memoryleak?)
⑥ 如何在Android用FFmpeg+SDL2.0解码显示图像
创建一个VideoPicture结构体用来保存解码出来的图森败像春隐。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* SDL_Lesson.c
*
* Created on: Aug 12, 2014
* Author: clarck
*/
#include <jni.h>
#include <android/native_window_jni.h>
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_events.h"
#include "../include/logger.h"
#include "../ffmpeg/include/libavcodec/avcodec.h"
#include "../ffmpeg/include/libavformat/avformat.h"
#include "../ffmpeg/include/libavutil/pixfmt.h"
#include "../ffmpeg/扒春厅include/libswscale/swscale.h"
#include "../ffmpeg/include/libswresample/swresample.h"
#define SDL_AUDIO_BUFFER_SIZE 1024
#define MAX_AUDIO_SIZE (5 * 16 * 1024)
#define MAX_VIDEO_SIZE (5 * 256 * 1024)
#define FF_ALLOC_EVENT (SDL_USEREVENT)
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
#define VIDEO_PICTURE_QUEUE_SIZE 1
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
typedef struct PacketQueue {
AVPacketList *first_pkt, *last_pkt;
int nb_packets;
int size;
SDL_mutex *mutex;
SDL_cond *cond;
} PacketQueue;
typedef struct VideoPicture {
SDL_Window *screen;
SDL_Renderer *renderer;
SDL_Texture *bmp;
AVFrame* rawdata;
int width, height; /*source height & width*/
int allocated;
} VideoPicture;
typedef struct VideoState {
char filename[1024];
AVFormatContext *ic;
int videoStream, audioStream;
AVStream *audio_st;
AVFrame *audio_frame;
PacketQueue audioq;
unsigned int audio_buf_size;
unsigned int audio_buf_index;
AVPacket audio_pkt;
uint8_t *audio_pkt_data;
int audio_pkt_size;
uint8_t *audio_buf;
DECLARE_ALIGNED(16,uint8_t,audio_buf2) [AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];
enum AVSampleFormat audio_src_fmt;
enum AVSampleFormat audio_tgt_fmt;
int audio_src_channels;
int audio_tgt_channels;
int64_t audio_src_channel_layout;
int64_t audio_tgt_channel_layout;
int audio_src_freq;
int audio_tgt_freq;
struct SwrContext *swr_ctx;
AVStream *video_st;
PacketQueue videoq;
VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
int pictq_size, pictq_rindex, pictq_windex;
SDL_mutex *pictq_mutex;
SDL_cond *pictq_cond;
SDL_Thread *parse_tid;
SDL_Thread *audio_tid;
SDL_Thread *video_tid;
AVIOContext *io_ctx;
struct SwsContext *sws_ctx;
int quit;
} VideoState;
VideoState *global_video_state;
⑦ Android 分析OOM工具介绍
如图1所示, 步骤
** 1, 2, 3** 为打开Android Monitor并切换标签到monitor的过程
4, 5, 6 对应的图标和文字含义分别是
MAT 工具识别,并解析hprof文件,
有两种方式可以获得hprof文件
MAT并不能直接打开这两个hprof, 必须通过hprof-conv来转换一次
如图3所示,选中(过滤出MainActivity), 然后通过Objects可以看出它有8个实例
接着选中 com.example.wowo.MainActivity 然后右键选择
Merge shortest paths to GC Roots -> exclude week references
因为弱引用是会被回收的,所以排除掉更加容易发现OOM.
什么是OOM out-of-memory?
Android下的APP运行在VM中(Dalvik or ART), 一个APP需要的内存是有限,这个值在不同的平台, 不同的手机上是不同的,当APP需要的内存超过了内存上限,就会引起OOM.
下面给出一个最基本的Android APP显示HelloWorld的例子.
这时如果不停的旋转屏幕, 这时通过观察Android Monitor里的Free和allocated的memory会发现 allocated 的memory会不断增加,而Free的memory会不断减小
这时通过图1中步聚5 mp java heap, 然后filter到MainActivity, 会发现MainActivity有多个实例
接着再通过MAT来分析, 图4所示
发现有很多FinalizerReference, 应该是与GC有关,由于旋转屏幕会导致MainActivity销毁并重新创建实例,而JVM在创建MainActivity实例时还有free的memory, 所以并没有触发GC,即原来的MainActivity的实例并没有被回收,所以多次旋转后,在free memory还有的情况下就会保存多个MainActivity的实例造成内存泄露的假象。当free memory 不够时,这时会触发GC, 会回收之前销毁的MainActivity的实例。
所以在查看OOM问题时,当allocated内存不断增大时,应该人为先触发GC(点击图1的4)。
如果allocated的内存没有下降,说明当前并没有可回收的实例占据内存了。
而在该例中,如果点击了initiate GC后,allocated的内存立即减少了。
Android Monitor看到MainActivity也就只有一个实例了。