Android优化笔记

作者: R7_Perfect | 来源:发表于2019-07-19 17:25 被阅读4次

    http优化 http协议组成

    https http2.0

    图片优化

    工程结构

    垃圾回收

    线程池内部实现

    链表结构

    锁机制

    线程与cpu

    hashmap原理

    启动优化

    MultiDex加载耗时

    优化方法数:尽量避免方法超过65535个

    少用一些不必要的框架:可以自己造轮子,或者找轻量级的框架

    慎用Kotlin

    Dex懒加载:配置multiDexKeepFile或者multiDexKeepProguard属性

    网络优化

    Gzip压缩

    1.IP直连与HttpDns

    接入HttpDns与Https验证host会有冲突

    重新OKhttp DNS的lookup方法

    将域名替换为ip地址

    将请求头中添加host属性,值为域名对应的ip地址

    2、Http1.1版本引入了“持久连接”,多个请求被复用

    Http2引入了“多工”、头信息压缩、服务器推送等特性

    多路复用,可以做到在一个连接并行的处理多个请求

    http2.0的协议解析采用二进制格式

    3. 合并网络请求,减少请求次数

    4. 网络缓存

    5. 数据更新采用增量,而不是全量,仅将变化的数据返回,客户端进行合并

    6. protoBuf:二进制消息非常紧凑

    Facebook的开源项目augmented-traffic-control可以模拟不同的网络环境,针对带宽、时延抖动、丢包率、错包率、包重排序率等方面,堪称弱网调试神器;

    图片优化

    使用WebP格式

    图片上传 避免整文件传输,采用分片传输

    Bitmap复用

    BitmapFactory.Options.inBitmap字段,设置此字段之后解码方法会尝试复用一张存在的Bitmap

    Bitmap压缩

    Bitmap.compress() 图片文件大小会变小,内存不变

    BitmapFactory.Options.inSampleSize 内存压缩

    HTTPS:

    对协商过程进行加密

    私钥一对多公钥

    非对称加密算法进行对称加密算法协商过程

    如何安全的获取公钥,并确保公钥的获取是安全的

    服务器发送了一个SSL证书给客户端,SSL 证书中包含的具体内容有证书的颁发机构、有效期、公钥、证书持有者、签名,通过第三方的校验保证了身份的合法、

    1)首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验

    (2)浏览器开始查找操作系统中已内置的受信任的证书发布机构CA,与服务器发来的证书中的颁发者CA比对,用于校验证书是否为合法机构颁发

    (3)如果找不到,浏览器就会报错,说明服务器发来的证书是不可信任的。

    (4)如果找到,那么浏览器就会从操作系统中取出  颁发者CA  的公钥,然后对服务器发来的证书里面的签名进行解密

    (5)浏览器使用相同的hash算法计算出服务器发来的证书的hash值,将这个计算的hash值与证书中签名做对比

    (6)对比结果一致,则证明服务器发来的证书合法,没有被冒充

    (7)此时浏览器就可以读取证书中的公钥,用于后续加密了


    HTTP

    1) 应用层: FTP, DNS, HTTP

    2) 传输层:TCP,UDP

    3) 网络层: 理在网络上流动的数据包,数据包是网络传输的最小数据单位

    4) 链路层: 处理连接网络的硬件部分

    1 2

    第一次握手客户端发送带有SYN标志的连接请求报文段,然后进入SYN_SEND状态,等待服务端的确认。

    第二次握手:服务端接收到客户端的SYN报文段后,需要发送ACK信息对这个SYN报文段进行确认。同时,还要发送自己的SYN请求信息。服务端会将上述的信息放到一个报文段(SYN+ACK报文段)中,一并发送给客户端,此时服务端将会进入SYN_RECV状态。

    第三次握手:客户端接收到服务端的SYN+ACK报文段后,会向服务端发送ACK确认报文段,这个报文段发送完毕后,客户端和服务端都进入ESTABLISHED状态,完成TCP三次握手。

    当三次握手完成后,TCP协议会为连接双方维持连接状态。为了保证数据传输成功,接收端在接收到数据包后必须发送ACK报文作为确认。如果在指定的时间内(这个时间称为重新发送超时时间),发送端没有接收到接收端的ACK报文,那么就会重发超时的数据。

    Http2

    二进制帧机制:HTTP/2 消息被分成很小的消息和frame,然后每个消息和frame用二进制编码。客户端和服务端都采用二进制编码和解码。

    :已经建立的连接之间双向流动的字节,它能携带一个至多个消息。

    消息:一个完整的帧序列,它映射到逻辑的请求和响应消息。

    :在HTTP/2通信的最小单元。每个桢包括一个帧头,里面有个很小标志,来区别是属于哪个流。

    所有的通信都建立在一个TCP连接上,可以传递大量的双向流通的流。

    每个流都有独一无二的标志和优先级。

    每个消息都是逻辑上的请求和相应消息。由一个或者多个帧组成。

    来自不同流的帧可以通过帧头的标志来关联和组装起来

    请求和响应的多路复用:通过允许客户端和服务端把HTTP多条消息分解成独立的帧,交错传输,然后在另一端组装.

    流量控制:HTTP / 2没有规定用于实现流量控制的任何特定算法。相反,它提供了简单的构建模块并将实现推迟到客户端和服务器,这可以用它来实现自定义策略来调节资源使用和分配,以及实现新的传输功能,这可能有助于提高Web应用程序真实性和感知性。

    服务端推送:HTTP / 2的另一个强大的新功能是服务器为单个客户端请求发送多个响应的能力。也就是说,除了对原始请求的响应之外,服务器还可以向客户端推送额外的资源

    头部压缩:HTTP / 2使用两种简单但强大的技术使用HPACK压缩格式

    内存优化:

    尽早将不用的引用对象赋为null

    使用SoftReference

    数组,树,图,链表等使用结束应立即置为null

    当程序有一定的等待时间,System.gc()

    能用基本类型如int,long,就不用Integer,Long对象

    静态变量属于全局变量,不会被GC回收,属于永久区

    节制地使用Service,使用JobScheduler

    SparseArray

    nano protobufs序列化数据,通常的protobufs会生成冗余代码,会导致可用内存减少,Apk体积变大,运行速度减慢

    使用try catch进行捕获,对高风险OOM代码块如展示高清大图等进行try catch

    工具:MAT,LeakCanary

    检测Block

    StickMode 可以设置不同的线程检测策略、虚拟机检测策略。

    TraceView

    AndroidPerformanceMonitor

    ANR-WatchDog

    Apk瘦身

    移除无用代码、功能

    启用Proguard

    缩减方法数

    Drawable目录只保留一份资源

    对图片进行压缩

    PNG转换JPG

    使用矢量图

    资源混淆 AndResGuard

    So瘦身:对于性能敏感模块使用的So可以都放在armeabi目录,然后通过代码判断设备的CPU类型,再加载其对应架构的SO文件

    锁机制

    synchronized

    普通方法同步

    线程2需要等待线程1的method1执行完成才能开始执行method2方法

    静态方法(类)同步

    对静态方法的同步本质上是对类的同步,所以即使test和test2属于不同的对象,但是它们都属于SynchronizedTest类的实例,所以也只能顺序的执行method1和method2

    总结

    每个对象都有个monitor对象,加锁就是在竞争monitor对象

    代码块加锁是在前后分别加上monitorenter和monitorexit指令来实现的方法

    加锁是通过一个标记位来判断的


    ReentrantLock

    相比于synchronized,ReentrantLock在功能上更加丰富,它具有可重入、可中断、可限时、公平锁等特点。

    锁分类

    1.可重入锁

    也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响

    2.公平锁/非公平锁

    公平锁(Fair):加锁前检查是否有排队等待的线程,优先排队等待的线程,先来先得

    非公平锁(Nonfair):加锁时不考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待

    3.互斥锁/共享锁

    独占锁模式下,每次只能有一个线程能持有锁

    共享锁,则允许多个线程同时获取锁,并发访问 共享资源,如:ReadWriteLock。

    4.悲观锁/乐观锁

    悲观锁:假定会发生并发冲突

    乐观锁:假设不会发生并发冲突:一般是通过为数据库表增加一个 “version” 字段来实现。读取出数据时,将此版本号一同读出,之后更新时,对此版本号加一。此时,将提交数据的版本数据与数据库表对应记录的当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则予以更新,否则认为是过期数据。

    5.偏向锁/轻量级锁/重量级锁

    Synchronized底层优化(偏向锁、轻量级锁)https://www.cnblogs.com/paddix/p/5405678.html

    6.分段锁

    假如容器里有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效提高并发访问效率,这就是ConcurrentHashMap所使用的锁分段技术

    7.自旋锁

    互斥同步对性能最大的影响是阻塞的实现,挂起线程和恢复线程的操作都需要转入内核态中完成,这些操作给系统的并发性能带来了很大的压力。 同时,虚拟机的开发团队也注意到在许多应用上,共享数据的锁定状态只会持续很短的一段时间,为了这段时间去挂起和恢复线程并不值得。 如果物理机器有一个以上的处理器,能让两个或以上的线程同时并行执行,我们就可以让后面请求锁的那个线程“稍等一下”,但不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。 为了让线程等待,我们只需让线程执行一个忙循环(自旋),这项技术就是所谓的自旋锁。

    锁优化

    Java高效并发之锁优化 https://blog.csdn.net/sted_zxz/article/details/76854371

    相关文章

      网友评论

        本文标题:Android优化笔记

        本文链接:https://www.haomeiwen.com/subject/brbslctx.html