内存优化

Android 性能优化实战 - 直播间场景 「涉及到 Kotl

2022-05-25  本文已影响0人  badmask

说一下场景

线上总有反馈说从直播间掉线,然后测试开始压测,发现对于低端设备在我们业务中推流场景下只能到60,即会发生异常;

先说一下优化前的问题

优化前业务流程图.png

优化思路

优化实战

优化后业务流程图.png

二次分发

otherFlow, liveFlow, highFreqFlow 均为 MutableSharedFlow;
其中 extraBufferCapacity 分别为 5, 800, 300「5:基本不会有积压; 800:重要流程消息,为防止被丢弃设为 较高阀值,服务端目前最高并发貌似也不会超过 800; 300:评论,送礼都是可丢弃的,且评论区最高存储消息 count 为 150」;
onBufferOverflow 均为 BufferOverflow.DROP_OLDEST;
处理之后也解决了 special cmd 无法及时处理,导致退房的bug.

Gson 解析

对于刚需字段 command,初次解析后,在 ws 的 data 里增加一个 command 即可, so easy.

data class Broadcast(val message: JSONObject, val command: Int)

对于 Gson 解析,改之前写法如下

val a = jsonString.optJSONObject("A")?.toString() ?: ""
val b = jsonString.optJSONObject("B")?.toString() ?: ""
val aa = try {
    GsonManager.gson().fromJson<User>(a, object : TypeToken<User>() {}.type)
} catch (e: Exception) {
    User()
}
val bb = GsonManager.gson().fromJson<User>(b, object : TypeToken<User>() {}.type)
val c = jsonString.optLong("c")
val d = jsonString.optInt("d")
var e = jsonString.optString("e", "")
val f = jsonString.optBoolean("f", false)
val g = jsonString.optJSONObject("g")?.toString() ?: ""
val extra = try {
    GsonManager.gson().fromJson<CCC>(g, object : TypeToken<CCC>() {}.type)
} catch (e: Throwable) {
    null
}

改完后

val data = try {
    GsonManager.gson().fromJson<AB>(jsonString, object : TypeToken<AB>() {}.type)
} catch (e: Throwable) {
    return
}

data class AB(
    @SerializedName("a")
    var a: User,
    @SerializedName("b")
    var b: User,
    @SerializedName("c")
    var c: Long,
    @SerializedName("d")
    var d: Int,
    @SerializedName("e")
    var e: String,
    @SerializedName("f")
    var f: Boolean? = null,
    @SerializedName("g")
    var g: CCC? = null,
)

至于 Gson 解析耗时原理的话,自行查阅吧,我也不太熟...

其他优化

在对上面的 totalFlow 做初步解析的时候,用到了很多 filter 方法,每一次 filter 都是新建的一个 flow,尽量一次 filter 完成功能,如下

public inline fun <T> Flow<T>.filter(crossinline predicate: suspend (T) -> Boolean): Flow<T> = transform { value ->
    if (predicate(value)) return@transform emit(value)
}

//优化前如下:
flow.filter {
//**
}.map {
//***
}.filter {
//**
}.catch {
//**
}

//优化后如下:
flow.mapNotNull{
//**
}.catch {
//**
}

另外对于疯狂刷评论等操作,肯定会导致 评论区的UI 疯狂刷新,可以新建一个队列缓存 comment msg,每秒取 3-4 次,每次取的 msg count 根据设备 level 来定,减少 UI 绘制压力;

成果

单丛直播压测的角度来讲,对于低端设备,结论如下:


成果.png

优化前 推流-评论-60 掉线;
注:以上数字为每秒发送聊天消息*条;

卡顿检测工具

说一下发现 gson 耗时的检测工具:
这版优化前,还有一版优化,当时发现的问题是大量 gson 解析发生在 UI thread, 看下图:


cpu profiler.png

原因是: ws 接收的 coroutine dispatcher 是 Main.
不过也能发现 gson 耗时问题.

拓展
目前进一步的优化所用工具为 tencent matrix.

上一篇 下一篇

猜你喜欢

热点阅读