字节跳动:IO优化是怎么作的,你还看不明白

2021年09月15日 阅读数:4
这篇文章主要向大家介绍字节跳动:IO优化是怎么作的,你还看不明白,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。
  • 高性能 实时写入
  • 稳定 防crashandroid

  • 多进程访问 git

    经过与 Android 开发同窗的沟通,了解到系统自带的 SharedPreferences 对多进程的支持很差。 github

    现有基于 ContentProvider 封装的实现,虽然多进程是支持了,可是性能低下,常常致使 ANR。 面试

    考虑到 mmap 共享内存本质上的多进程共享的,咱们在这个基础上,深刻挖掘了 Android 系统的能力,提供了多是业界最高效的多进程数据共享组件。算法

  • 匿名内存 markdown

    在多进程共享的基础上,考虑到某些敏感数据(例如密码)须要进程间共享,可是不方便落地存储到文件上,直接用 mmap 不合适。 架构

    咱们了解到 Android 系统提供了 Ashmem 匿名共享内存的能力,发现它在进程退出后就会消失,不会落地到文件上,很是适合这个场景。 app

    咱们很愉快地提供了 Ashmem MMKV 的功能。less

  • 数据加密 ide

    不像 iOS 提供了硬件层级的加密机制,在 Android 环境里,数据加密是很是必须的。

    MMKV 使用了 AES CFB-128 算法来加密/解密。咱们选择 CFB 而不是常见的 CBC 算法,

    主要是由于 MMKV 使用 append-only 实现插入/更新操做,流式加密算法更加合适。

  • 数据有效性

1.3性能对比

咱们将 MMKV 和 SharedPreferences、SQLite 进行对比, 重复读写操做 1k 次。相关测试代码在 Android/MMKV/mmkvdemo/。结果以下图表。

单进程性能

字节跳动:IO优化是怎么作的,你还看不明白

可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。

字节跳动:IO优化是怎么作的,你还看不明白

可见,MMKV 不管是在写入性能仍是在读取性能,都远远超越 MultiProcessSharedPreferences & SQLite & SQLite, MMKV 在 Android 多进程 key-value 存储组件上是不二之选。

1.3 MMKV 原理

  • 内存准备?经过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操做系统负责将内存回写到文件,没必要担忧 crash 致使数据丢失。

  • 数据组织?数据序列化方面咱们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。

  • 写入优化?考虑到主要使用场景是频繁地进行写入更新,咱们须要有增量更新的能力。咱们考虑将增量 kv 对象序列化后,append 到内存末尾。 这样同一个 key 会有新旧若干份数据,最新的数据在最后;那么只需在程序启动第一次打开 mmkv 时,不断用后读入的 value 替换以前的值,就能够保证数据是最新有效的。

  • 空间增加?使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增加得不可控。咱们须要在性能和空间上作个折中。 之内存 pagesize 为单位申请空间,在空间用尽以前都是 append 模式;当 append 到文件末尾时,进行文件重整、key 排重,尝试序列化保存排重结果; 排重后空间仍是不够用的话,将文件扩大一倍,直到空间足够。

  • 数据有效性?考虑到文件系统、操做系统都有必定的不稳定性,咱们另外增长了 crc 校验,对无效数据进行甄别。

更详细的设计原理参考?[MMKV 原理](

)。

1.4 快速上手


  dependencies {

      implementation 'com.tencent:mmkv:1.0.23'

      // replace "1.0.23" with any available version

  }

[MMKV](

)的使用很是简单, 全部变动立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录 (默认/data/data/xxx.xxx/files/mmkv/) (sp存储在/data/data/xxx.xxx/shared_prefs/)

支持从SP迁移数据importFromSharedPreferences

MMKV 还额外实现了一遍 SharedPreferences、SharedPreferences.Editor 这两个 interface


  // 能够跟SP用法同样

  SharedPreferences.Editor editor = mmkv.edit();

  // 无需调用 commit()

  //editor.commit();

MMKV 的使用很是简单,全部变动立马生效,无需调用 sync、apply。 在 App 启动时初始化 MMKV,设定 MMKV 的根目录(files/mmkv/),例如在 MainActivity 里:


  protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      String rootDir = MMKV.initialize(this);

      System.out.println("mmkv root: " + rootDir);

      //……

  }

MMKV 提供一个全局的实例,能够直接使用:


  import com.tencent.mmkv.MMKV;

  //……

  MMKV kv = MMKV.defaultMMKV();

  kv.encode("bool", true);

  boolean bValue = kv.decodeBool("bool");

  kv.encode("int", Integer.MIN_VALUE);

  int iValue = kv.decodeInt("int");

  kv.encode("string", "Hello from mmkv");

  String str = kv.decodeString("string");

使用完毕的几个方法


      public native void clearAll();

      // MMKV's size won't reduce after deleting key-values

      // call this method after lots of deleting f you care about disk usage

      // note that `clearAll` has the similar effect of `trim`

      public native void trim();

      // call this method if the instance is no longer needed in the near future

      // any subsequent call to the instance is undefined behavior

      public native void close();

      // call on memory warning

      // any subsequent call to the instance will load all key-values from file again

      public native void clearMemoryCache();

      // you don't need to call this, really, I mean it

      // unless you care about out of battery

      public void sync() {

          sync(true);

      }

1.5 补充适用建议

若是使用请务必作code19版本的适配,这个在github官网有说明

依赖下面这个库,而后对19区分处理

implementation ‘com.getkeepsafe.relinker:relinker:1.3.1’



  if (android.os.Build.VERSION.SDK_INT == 19) {

      MMKV.initialize(relativePath, new MMKV.LibLoader() {

### 最后

但愿本文对你有所启发,有任何面试上的建议也欢迎留言分享给你们。

好了,今天的分享就到这里,若是你对在面试中遇到的问题,或者刚毕业及工做几年迷茫不知道该如何准备面试并突破现状提高本身,对于本身的将来还不够了解不知道给如何规划,**来看看同行们都是如何突破现状,怎么学习的,来吸取他们的面试以及工做经验完善本身的以后的面试计划及职业规划。**

**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://ali1024.coding.net/public/P7/Android/git)**

![](https://s2.51cto.com/images/20210912/1631459114169029.jpg)

好了~若是你看到了这里,以为文章写得不错就给个赞呗?若是你以为那里值得改进的,请给我留言。必定会认真查询,修正不足。谢谢。

![](https://s2.51cto.com/images/20210912/1631459114328225.jpg)

>为何某些人会一直比你优秀,是由于他自己就很优秀还一直在持续努力变得更优秀,而你是否是还在知足于现状心里在窃喜!但愿读到这的您能点个小赞和关注下我,之后还会更新技术干货,谢谢您的支持!