如何写出GC友好的应用

作者:乐蛙科技高级研发经理 易宁

Android应用普遍没有iOS应用流畅,这与Android应用是运行在Java虚拟机上有很大的关系,而关系最大的恐怕就是Java虚拟机上的Garbage Collection(GC)了。Java语言提供了自动内存管理,垃圾对象会在GC过程中自动被释放。这提供了开发效率,使开发者能集中精力在业务逻辑上;但天下没有免费的午餐,你写的Android应用的某些性能上的问题很可能就是GC导致的。

下面是一段非常简单的Java语句:

1
byte[] data = new byte[512 * 512 * 4];

这条语句申请了一块大小相等于512*512大小图片的内存。执行这条语句会消耗多少时间呢?0+ms吗?基本没有性能影响吗?

[译]Zygote

原文地址:Zygote https://anatomyofandroid.com/2013/10/15/zygote/

Zygote(受精卵)是一个启动应用的守护进程,在Server Manager之后被init.rc触发,但其实他是真正被app_process启动的,下面是启动这个特殊进程的流程。

1
2
3
4
5
6
7
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd

你可以发现Zygote是如何当做系统服务启动的,你也可以看到app_process为什么说app_process是启动Zygote的真正命令。就像之前说的,Zygote是一个以专门启动应用为的守护进程。这意味着Zygote是所有App进程的父进程。当app_process启动Zygote时,它通过调用Zygote的main()方法创建了第一个Dalvik虚拟机。当Zygote启动后,zygote会预加载所有必须的Java类和资源,启动System Server并打开一个名为/dev/socket/zygote的socket服务,去监听所有启动应用的请求。 想之前的文章所说,System Server 是一个和它的父进程完全分离的进程。一旦System Server创建完成,它会初始化一系列不同的System Services并启动Activity Manager。那Zygote是如何启动新的应用的呢?

如何使用ddmlib dump出堆文件

一般情况下如果我想要较详细的分析内存状况,会使用android monitor(下简称monitor)和Memory Analyzer工具(下简称MAT),但步骤有些麻烦。

  1. 使用monitor dump堆文件
  2. 使用hprof-conv工具,将hprof转换成MAT能够识别的格式
  3. 使用MAT分析

需要手动dump hprof再使用hprof-conv工具手动转码,上篇Android Bitmap的内存大小是如何计算的?说到使用square的haha来做内存堆中Bitmap的分析。所以在思考如何一键完成内存dump和analyze的过程,当然也可以任意其他Java对象做分析。
如何完成dump和转码,思路还是Read the fucking source code,看下monitor是如何dump hprof文件的。打开Android sdk目录,monitor和其依赖的jar分别在/tools和’/tools/lib’目录,核心代码在ddmlib.jar中,Java swring代码在ddms.jarddmuilib.jar中,ddmlib需要依赖common.jarguava.jar

Android Bitmap的内存大小是如何计算的?

一、前言

本来只想说下Bitmap和内存的基本关系,但发现如果真的想把这看似简单的事情说清楚,实际上未必那么简单,你不信?不妨先尝试下回答下面几个问题!

  • 问1:什么是dpi?什么是dp?答:你在侮辱我?我拒绝回答!(:无辜脸
  • 问2:以Nexus6为例,分辨率1440*2560,5.96英寸,ppi是什么?dpi是什么?1dp是多少像素?
  • 问3:还以Nexus6为例,一张180*180的图片,放置在设置了wrap_content属性的ImageView中,当这张图片,分别放在drawable-nodpi,drawable-mdpi,drawable-hdpi, drawable-xxhdpi,drawable-xxxhdpi这几个资源目录中,在屏幕上分别显示多大(像素)的图片?
  • 问4:这张图片占用的内存大小分别为多少?
  • 问5:如果设置ImageView的宽和高为固定的值,如50px,那么上述情况下,加载的Bitmap占用内存大小分别为多大?

本文主要围绕上述问题,介绍Android图片资源加载的基本机制,图片的内存大小如何计算,以及内存图片分析工具。

Mac OS上编译Android源码

一、制作一个大小写敏感的磁盘分区

1.1.Mac OS磁盘工具

这里我使用一块移动硬盘,将移动硬盘的一个分区使用Mac OS的硬盘工具,抹掉数据,选择MacOS扩展(区分大小写,日志式),创建成大小写敏感的分区。

这里会遇到一个问题,抹掉分区数据的时候,会报错:“Mac OSX 抹盘发生错误:Mediakit 报告设备上空间不足以执行此操作”,这里的原因是磁盘没有大于200M的UEFI分区。

Mac/Linux下gcc编译动态链接库[.so文件]

一、以bsdiff.c和bspatch.c为例编译bsdiff.so

bsdiff.c和bspatch.c分别依赖bzip2

项目结构

步骤

  • 使用BsDiff.java生成BsDiff.class文件

    javac ivonhoe/spring/wrcenter/jni/BsDiff.java

  • 生成BsDiff.h文件

    javah ivonhoe.spring.wrcenter.jni.BsDiff

  • 生成bspatch.o