dump java 原理_dumpsys实现原理
概述
dumpsys是一个android手机里面的可执行文件。
从名字就可以看出,主要是用于dump 当前android system的一些信息。比如
activity(当前系统中所有activity的堆栈关系)
alarm(当前系统中所有的Alarms)
等等,是一项分析手机问题,运行状态,使用情况等十分有效的手段。
查看所支持的dump选项
adb shell dumpsys -l
会列出所有可以dump的选项,比如想获取所有window相关的信息,可以使用命令
adb shell dumpsys window
实现逻辑
既然是一个可执行文件,必然是先找到其mk文件:/frameworks/native/cmds/dumpsys/Android.mk
...
LOCAL_SRC_FILES:= \
dumpsys.cpp
...
LOCAL_MODULE:= dumpsys
include $(BUILD_EXECUTABLE)
dumpsys的源码结构其实很简单,只有一个dumpsys.cpp
/frameworks/native/cmds/dumpsys/dumpsys.cpp
int main(int argc, char* const argv[])
{
...
sp sm = defaultServiceManager();
...
Vector services;
...
services = sm->listServices();
...
const size_t N = services.size();
for (size_t i=0; i
sp service = sm->checkService(services[i]);
...
int err = service->dump(STDOUT_FILENO, args);
...
}
return 0;
}
先通过defaultServiceManager()函数获得ServiceManager对象,然后根据dumpsys传进来的参数通过函数checkService来找到具体的service, 并执行该service的dump方法,达到dump service的目的。
实例讲解
因为笔者最近在研究手机跑2D/3D场景的性能评测,所以这里以dumpsys gfxinfo 为例,说下它的大致流程。
具体服务
由上文可以知道,dumpsys的实现其实是根据参数来找到某个具体的service,然后执行其dump方法。
我们熟悉的系统service有ActivityManagerSerice(activity),WindowManagerService(window)等,那gfxinfo具体对应的是哪个service呢?
在文件:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java中有下面这段代码
public void setSystemProcess() {
...
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
...
}
在ams里面,通过ServiceManager添加了一个name为gfxinfo的serivce叫GraphicsBinder,该service就是gfxinfo对应的service.
static class GraphicsBinder extends Binder {
...
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump gfxinfo from from pid="
+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ " without permission " + android.Manifest.permission.DUMP);
return;
}
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
}
}
这里有一个权限检查,如果app想要dump系统信息必须要配置 android.Manifest.permission.DUMP 权限,而该权限是三方app没办法使用的。
那作为一个三方app,我们有办法 绕过 该权限检查吗?这里按下不表,接着往后看。
ActivityThread
当我们执行adb shell dumpsys gfxinfo的时候,其实最后执行的是ams中的dumpGraphicsHardwareUsage该方法。
final void dumpGraphicsHardwareUsage(FileDescriptor fd,
PrintWriter pw, String[] args) {
ArrayList procs = collectProcesses(pw, 0, false, args);
...
for (int i = procs.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = procs.get(i);
if (r.thread != null) {
...
r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
...
}
}
}
可以看出,最后真正做dump动作的,其实是r.thread这个对象,这里直接给出r.thread其实就是ActivityThread中的内部类:ApplicationThread,省略代码的追查,让主线更加清晰。
collectProcesses函数的主要作用就是:根据参数找到对应的进程信息
该参数就是命令行中gfxinfo后面传进来的参数。
如果gfxinfo后面没有跟参数,则表示获取所有的Process信息
如果gfxinfo后面跟 包名, 则只获取指定报名的Process信息
文件:/frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
...
private class ApplicationThread extends ApplicationThreadNative {
...
@Override
public void dumpGfxInfo(FileDescriptor fd, String[] args) {
dumpGraphicsInfo(fd);
WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
}
...
}
}
Native-dumpGraphicsInfo实现
dumpGraphicsInfo是一个native函数实现在
/frameworks/base/core/jni/android_view_GLES20Canvas.cpp
static void
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
#ifdef USE_OPENGL_RENDERER
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
android::uirenderer::RenderNode::outputLogBuffer(fd);
#endif // USE_OPENGL_RENDERER
}
/frameworks/base/libs/hwui/RenderNode.cpp
void RenderNode::outputLogBuffer(int fd) {
DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
...
FILE *file = fdopen(fd, "a");
fprintf(file, "\nRecent DisplayList operations\n");
logBuffer.outputCommands(file);
String8 cachesLog;
Caches::getInstance().dumpMemoryUsage(cachesLog);
fprintf(file, "\nCaches:\n%s", cachesLog.string());
...
}
可以看出是打印了一些RenderNode的信息,包括memory和cache。
Native-ThreadedRenderer实现
/frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void dumpGfxInfo(FileDescriptor fd) {
...
HardwareRenderer renderer =
root.getView().mAttachInfo.mHardwareRenderer;
if (renderer != null) {
renderer.dumpGfxInfo(pw, fd);
}
...
}
HardwareRenderer是一个抽象类,具体的实现是在
/frameworks/base/core/java/android/view/ThreadedRenderer.java
@Override
void dumpGfxInfo(PrintWriter pw, FileDescriptor fd) {
pw.flush();
nDumpProfileInfo(mNativeProxy, fd);
}
nDumpProfileInfo也是一个native函数,也是去抓取一些graphic信息,不再做详细讲解。
到这里,dumpsys gfxinfo的流程就基本讲解完了。
总结
dumpsys的实现其实是通过serviceManager拿到对应的service信息,然后执行该service的dump函数。
需要注意的是:每个service都有一个权限检查,需要系统app才可以dump。
dump java 原理_dumpsys实现原理相关推荐
- java 字节码增强原理_深入浅出Java探针技术1--基于java agent的字节码增强案例
Java agent又叫做Java 探针,本文将从以下四个问题出发来深入浅出了解下Java agent 一.什么是java agent? Java agent是在JDK1.5引入的,是一种可以动态修改 ...
- 深入掌握Java技术 EJB调用原理分析
深入掌握Java技术 EJB调用原理分析 一个远程对象至少要包括4个class文件:远程对象:远程对象的接口:实现远程接口的对象的stub:对象的skeleton这4个class文件. 在 ...
- java.lang.ThreadLocal实现原理和源码分析
java.lang.ThreadLocal实现原理和源码分析 1.ThreadLocal的原理:为每一个线程维护变量的副本.某个线程修改的只是自己的副本. 2.ThreadLocal是如何做到把变量变 ...
- java gc的工作原理、如何优化GC的性能、如何和GC进行有效的交互
java gc的工作原理.如何优化GC的性能.如何和GC进行有效的交互 一个优秀的Java 程序员必须了解GC 的工作原理.如何优化GC的性能.如何和GC进行有效的交互,因为有一些应用程序对性能要求较 ...
- Java程序的运行原理及JVM的启动是多线程的吗?
Java程序的运行原理及JVM的启动是多线程的吗? A:Java程序的运行原理 Java通过java命令会启动java虚拟机.启动JVM,等于启动了一个应用程序,也就是启动了一个进程. 该进程会自动启 ...
- 【Java 虚拟机原理】JDK 体系结构 | Java 源码运行原理 | Java 虚拟机内存
文章目录 一.JDK 体系结构 二.Java 源码运行原理 三.Java 虚拟机内存结构 一.JDK 体系结构 JDK 体系结构 : 下图所有的内容都是 JDK 体系中的组成元素 ; Java Lan ...
- java高级----Java动态代理的原理
Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程 ...
- Java基础 HashMap实现原理及方法
1.什么是HashMap? HashMap通常提起他,我们想到的就是键值对方式存储(key-value型式),可以接收null键值和null值.基于Map接口的非同步实现(也就是线程不安全),并不保证 ...
- Java集合 LinkedList的原理及使用
1.LinkedList的概述 2.LinkedList的常用方法 3.LinkedList的三种便利方式 4.LinkedList的总结 1.LinkedList的概述 LinkedList和Arr ...
最新文章
- 卫星覆盖区域分析 基于网格点法
- Zencart获取PayPal PDT Token参数教程方法
- OpenCV平面跟踪planar tracking的实例(附完整代码)
- python ssh实现_SSH协议的Python实现paramiko
- 61二叉搜索树的第k个结点
- 第七章—JavaScript数组
- 删除 字符串中‘*’号 两端的除外。指针h、p分别指向第一个和最后一个字符
- 自己动手写处理器之第一阶段(3)——MIPS32指令集架构简单介绍
- 使用批处理文件来操作注册表
- CentOS 6.7 x64 使用pptpd搭建***服务器
- 安阳7中计算机绘画知识,安阳工学院绘画专业主修课程有哪些
- NOD32反病毒系统升级
- EBS系统常见问题与故障
- jeff dean_Jeff Dean的构建大型分布式系统的软件工程建议
- C++ std::string 不可初始化为NULL及基本用法
- PV、UV、访问次数、跳出率、转化率、平均访问时长
- 前端是什么,是干嘛的
- the owning Session was closed
- 导之以行——儿子喝酸奶篇
- Kafka kafka-reassign-partitions.sh 命令使用