【官方博客】StrictMode API for Built-In Performance Monitoring

http://android-developers.blogspot.com/2010/12/new-gingerbread-api-strictmode.html

StrictMode API for Built-In Performance Monitoring

[This post is by Brad Fitzpatrick, an Android Software Engineer who worries unreasonably about responsiveness. —Tim Bray]

Back Story

One great thing about Google is “20% time”: spending 20% of your time working on projects outside your main focus area. When I joined Google, I bounced all over the place, often joking that I had seven 20% projects. One project I kept coming back to was Android. I loved its open nature, giving me access to do whatever I wanted, including opening my garage door when I approached my house on my motorcycle. I really wanted it to succeed but I worried about one thing: It wasn’t always super smooth. Animations would sometimes stutter and UI elements weren’t always immediately responsive to input. It was pretty obvious that things were sometimes happening on the wrong thread.

As a heavy SMS user, one of my 20% projects during the Cupcake (Android 1.5) release was speeding up the Messaging app and making it feel smoother. I got the app to a happy state and then continued bouncing between other 20% projects. When the Donut (Android 1.6) release came out, I noticed that a few of my Messaging optimizations had been accidentally broken. I was sad for a bit but then I realized what Android really needed was always-on, built-in, pervasive performance monitoring.

I joined the Android team full-time just over a year ago and spent a lot of time investigating Froyo performance issues, in particular debugging ANRs (those annoying dialogs you get when an application stalls its main thread’s Looper). Debugging ANRs with the tools at hand was painful and boring. There wasn’t enough instrumentation to find the causes, especially when multiple processes were involved (doing Binder or ContentResolver operations to Services or ContentProviders in other processes). There had to be a better way to track down latency hiccups and ANRs...

Enter StrictMode

“I see you were doing 120 ms in a 16 ms zone...”

StrictMode is a new API in Gingerbread which primarily lets you set a policy on a thread
declaring what you’re not allowed to do on that thread, and what the
penalty is if you violate the policy. Implementation-wise, this policy
is simply a thread-local integer bitmask.

By default
everything is allowed and it won’t get in your way unless you want it
to. The flags you can enable in the thread policy include:

  • detect disk writes
  • detect disk reads
  • detect network usage
  • on a violation: log
  • on a violation: crash
  • on a violation: dropbox
  • on a violation: show an annoying dialog

In addition, StrictMode has about a dozen hooks around most of the places that hit the disk (in java.io.*, android.database.sqlite.*, etc) and network (java.net.*) which check the current thread’s policy, reacting as you’ve asked.

StrictMode’s powerful part is that the per-thread policies are propagated whenever Binder IPC calls are made to other Services or Providers, and stack traces are stitched together across any number of processes.

Nobody wants to be slow

You
might know all the places where your app does disk I/O, but do you know
all the places where the system services and providers do? I don’t.
I’m learning, but it’s a lot of code. We’re continually working to
clarify performance implications in the SDK docs, but I usually rely on
StrictMode to help catch calls that inadvertently hit the disk.

Background on disks on phones

Wait,
what’s wrong with hitting the disk? Android devices are all running
flash memory, right? That’s like a super-fast SSD with no moving parts?
I shouldn’t have to care? Unfortunately, you do.

You can’t
depend on the flash components or filesystems used in most Android
devices to be consistently fast. The YAFFS filesystem used on many
Android devices, for instance, has a global lock around all its
operations. Only one disk operation can be in-flight across the entire
device. Even a simple “stat” operation can take quite a while if you
are unlucky. Other devices with more traditional block device-based
filesystems still occasionally suffer when the block rotation layer
decides to garbage collect and do some slow internal flash erase
operations. (For some good geeky background reading, see lwn.net/Articles/353411)

The
take-away is that the “disk” (or filesystem) on mobile devices is
usually fast, but the 90th percentile latencies are often quite poor.
Also, most filesystems slow down quite a bit as they get more full.
(See slides from Google I/O Zippy Android apps talk, linked off code.google.com/p/zippy-android)

The “main” Thread

Android callbacks and lifecycle events all typically happen on the main thread
(aka “UI thread”). This makes life easier most of the time, but it’s
also something you need to be careful of because all animations,
scrolls, and flings process their animations by callbacks on the main
thread.

If you want to run an animation at 60 fps and an input
event comes in (also on the main thread), you have 16 ms to run your
code reacting to that input event. If you take longer than 16 ms,
perhaps by writing to disk, you’ve now stuttered your animation. Disk
reads are often better, but they can also take longer than 16 ms,
especially on YAFFS if you’re waiting for the filesystem lock that’s
held by a process in the middle of a write.

The network is
especially slow and inconsistent, so you should never do network
requests on your main thread. In fact, in the upcoming Honeycomb
release we’ve made network requests on the main thread a fatal error,
unless your app is targeting an API version before Honeycomb. So if you
want to get ready for the Honeycomb SDK, make sure you’re never doing
network requests on your UI thread. (see “Tips on being smooth” below.)

Enabling StrictMode

The
recommended way to use StrictMode is to turn it on during development,
learn from it, and turn it off before you ship your app.

For example, in your application or component’s onCreate():

 public void onCreate() {     if (DEVELOPER_MODE) {         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()                 .detectDiskReads()                 .detectDiskWrites()                 .detectNetwork()                 .penaltyLog()                 .build());     }     super.onCreate(); }

Or, simply:

    public void onCreate() {     if (DEVELOPER_MODE) {         StrictMode.enableDefaults();     }     super.onCreate(); }

That latter form was specifically added so you can target pre-Gingerbread API versions but still easily enable StrictMode using reflection or other techniques. For instance, you could be targeting Donut (Android 1.6) but still use StrictMode if you’re testing on a Gingerbread device or emulator, as long as you use enough Reflection to call StrictMode.enableDefaults().

Watching StrictMode

If you’re using penaltyLog(), the default, just run adb logcat and watch the terminal output. Any violations will be logged to your console, slightly rate-limited for duplicate elimination.

If you want to get fancier, turn on penaltyDropbox() and they’ll be written to the DropBoxManager, where you can extract them later with
adb shell dumpsys dropbox data_app_strictmode --print

Tips on being smooth

In addition to Thread and java.util.concurrent.*, check out some of the Android APIs such as Handler, AsyncTask, AsyncQueryHandler, and IntentService.

Our Experience

During
Android development we have a new “dogfood” build each day that the
whole team uses. Throughout the development of Gingerbread we set up
our daily dogfood builds to enable StrictMode logging and upload all
found violations for analysis. Every hour a MapReduce job runs and
produces an interactive report of all the event loop stalls, their stack
traces (including cross-process ones), their latency percentiles, which
processes/packages they appear in, etc.

Using the data from
StrictMode we fixed hundreds of responsiveness bugs and animation
glitches all across the board. We made performance optimizations in the
Android core (e.g. system services and providers) so all apps on the
system will benefit, as well as fixing up tons of app-specific issues
(in both AOSP apps and Google
apps). Even if you’re using Froyo today, the recent updates to GMail,
Google Maps, and YouTube all benefited from StrictMode data collection
gathered on Gingerbread devices.

Where we couldn’t automatically
speed up the system, we instead added APIs to make certain patterns
easier to do efficiently. For example, there is a new method SharedPreferences.Editor.apply(), which you should be using instead of commit() if you don’t need commit()’s return value. (It turns out almost nobody ever checks it.) You can even use reflection to conditionally use apply() vs. commit() depending on the user’s platform version.

Googlers
who switched from Froyo to Gingerbread without seeing all the baby
steps between were shocked at how much more responsive the system
became. Our friends on the Chrome team then recently added something similar.
Of course, StrictMode can’t take all the credit. The new concurrent
garbage collector in Gingerbread also greatly reduces latency hiccups.

The Future

The
StrictMode API and its capabilities will continue to expand. We have
some good stuff lined up for StrictMode in Honeycomb but let us know
what else you’d like to see! I’ll be answering questions on stackoverflow.com for questions tagged “strictmode”. Thanks!

Posted by
Unknown

at
11:02 PM

Labels:
Performance,
Profiling,
strictmode,
Testing

时间: 2024-08-03 05:26:39

【官方博客】StrictMode API for Built-In Performance Monitoring的相关文章

Android 官方博客 - Android应用程序的内存分析(翻译)(转)

转自:http://www.cnblogs.com/wisekingokok/archive/2011/11/30/2245790.html Dalvik虚拟机支持垃圾收集,但是这不意味着你可以不用关心内存管理.你应该格外注意移动设备的内存使用,在上面内存空间是受到限制的.在这篇 文章里面,我们来看看Android SDK里面的一些内存剖析工具(profiling tools)是如何帮助我们修整应用程序的内存使用. 一些内存使用问题是很明显的,例如,如果在每次用户触摸屏幕的时候应用程序有内存泄露

欢迎加入51CTO官方博客QQ群112163514

大家好,我是51CTO博客小管家--奋斗的小歌.来到51CTO这个大家庭已经两周时间了,认识了不少IT技术达人,你们在我心中真的是棒棒哒! 感谢小伙伴们对51CTO技术博客的支持,特此开放51CTO官方博客QQ群112163514,这里会定期发布51CTO博客最新公告.活动及动态. 如果你喜欢IT技术,喜欢探讨技术问题,喜欢交流学习经验,那加入我们一定没错.这里拥有大批IT技术人才和技术文章,精彩好玩的活动,这里,是你找到志同道合朋友的乐园! 还等什么,赶快加入我们的51CTO官方博客QQ群,踏

腾讯DBA官方博客开通了,欢迎交流

腾讯DBA官方博客开通了,欢迎交流哈..麻烦给放到首页一下 http://tencentdba.com 腾讯互娱游戏DBA团队一直致力于为游戏提供稳定.高效的DB运营服务,这是我们团队的使命. 过去DBA团队一直专注于业务本身,没有太多精力将我们的技术及解决方案对外输出,因此,对于开通团队Blog的事宜,之前的筹划被无限期搁置... 2015新年伊始,我们终于将这个事情提上日程!新的起点,我们愿意将过去积累的经验及教训,及未来的成长及进步点滴,都记录下来,与大家同分享.共成长. 小伙伴们,一起加

【官方博客】Android’s HTTP Clients

Android’s HTTP Clients [This post is by Jesse Wilson from the Dalvik team. —Tim Bray] Most network-connected Android apps will use HTTP to send and receive data. Android includes two HTTP clients: HttpURLConnection and Apache HTTP Client. Both suppor

Dropbox 同步的工作方式,每个文件被分成4M的小块(官方博客)

http://www.zhihu.com/question/41544586 https://blogs.dropbox.com/tech/2014/07/streaming-file-synchronization/

div水平居中与垂直居中的方法【摘自美浩工作室官方博客 】

大家往往在写页面中会遇到不固定宽和高的div如果水平和垂直都居中呢?在写css的时候经常遇到的一个问题,当div没有固定的宽度或者高度的时候,如何才能让div水平或者垂直居中显示.如果div有固定宽度的话,用padding,margin都很容易实现.方法有很多种.不过经常遇到这种div没有固定的宽度高度的情况,我们就不能用margin,padding设置固定的距离了.这个问题让很多人头疼.而怎么样才能让这个div居中显示呢?其实这种情况解决的办法也是有很多种,js,css都可以实现. 1.先来看

常用控件产品官方文档/手册/API列表

.netCHARTING报表图表控件 文档帮助手册 Ab3d.PowerToys  文档帮助手册Ab3d.Reader3ds  文档帮助手册ABViewer  文档帮助手册(工程图纸文档管理系统)Active DJ Studio  文档帮助手册Active Sound Editor  文档帮助手册Active Sound Recorder  文档帮助手册ActivePatch  文档帮助手册(程序自动升级控件)Animated Chart  文档帮助手册BB FlashBack  文档帮助手册B

iOS_CNBlog项目开发 (基于博客园api开发)

按照惯例, 先上效果图 前言 很巧, 做这个项目是因为刚好在逛博客园的时候看到一篇文章 博客园第三方客户端-i博客园正式发布App Store, 这里就帮忙贴下链接啦, 毕竟我是由此而想说做这个项目的. 然而更巧的是, 和那篇文章的作者一样, 我也是刚毕业要找实习的人了(/(ㄒoㄒ)/~~), 开发容易找工不易, 哎, 做个项目练练手吧. 然后, 整个项目做下来大概做了半个月吧, 今天算是做出1.0版本啦, 已经贴上github(https://github.com/samAroundGitHu

Oracle官网JDK的API离线文档下载方法

最近在学习JAVA开发,使用频率最高的工具莫过于JAVA API,当我们身边没有可连接的网络,而又急需API文档时候,很明显我们需要在我们的电脑存储一份离线文档.下面是去Oracle官网下载API Documentation的步骤: 0.在地址栏输入http://www.oracle.com/index.html 进入Oracle官网,如下图: 1.把鼠标移到Downloads那里,不要点它哦!会看到展开一系列Oracle的产品下载,注意到第一列有个叫做“Popular Downloads” 红