① 如何用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也就只有一個實例了。