日本电影一区二区_日本va欧美va精品发布_日本黄h兄妹h动漫一区二区三区_日本欧美黄色

UME – 豐富的Flutter調(diào)試工具(flutter uri)

背景

目前西瓜視頻作者側(cè) Flutter 業(yè)務(wù)場景已經(jīng)覆蓋了 80% (包括視頻播放場景),用戶側(cè)核心場景包括我的 Tab 也已經(jīng)是 Flutter,在開發(fā)過程中,暴露了一些問題,debug 調(diào)試難、離開了 IDE 后猶如抓瞎、PM 設(shè)計(jì) QA 驗(yàn)收過程中拿不到有用的信息,在市面上找了一圈,也沒有類似 iOS Flex 這樣強(qiáng)大的調(diào)試工具,例如視圖大小、層級(jí)的展示,實(shí)例對(duì)象屬性的實(shí)時(shí)修改,網(wǎng)絡(luò)請(qǐng)求抓取,log 日志打印,文件查看等,因此西瓜視頻 Flutter 基礎(chǔ)團(tuán)隊(duì)決定開發(fā) UME 以解決上述問題。

介紹

UME (讀音:油米~) 是一個(gè) Flutter 調(diào)試工具包,內(nèi)部集成了豐富的調(diào)試小工具,設(shè)計(jì) UI、網(wǎng)絡(luò)、監(jiān)控、性能、logger 等,無論是研發(fā)、PM、還是 QA 均能使用。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

目前已實(shí)現(xiàn)的功能

  • 首頁功能支持拖拽排序展示當(dāng)前使用功能
  • Widget 信息展示widget 名稱widget 大小widget 文件路徑widget 代碼所在行
  • Widget 層級(jí)widget 構(gòu)建鏈支持 widget 搜索widget 信息展示renderObject 詳細(xì)信息展示
  • 網(wǎng)絡(luò)調(diào)試支持所有基于 http 包的等網(wǎng)絡(luò)請(qǐng)求抓取數(shù)據(jù)支持結(jié)構(gòu)化展示,長按可以復(fù)制到剪貼板收藏請(qǐng)求,單獨(dú)展示;清空非收藏列表請(qǐng)求過濾與搜索(支持部分匹配、正則匹配)請(qǐng)求導(dǎo)出 curl持久化與導(dǎo)出 HARmock 響應(yīng)內(nèi)容完整 har 文件映射修改單個(gè)字段結(jié)構(gòu)化信息長按復(fù)制
  • 內(nèi)存泄露支持自動(dòng)檢測由 route 打開的頁面Widget、State、Route 對(duì)象的內(nèi)存泄漏檢測
  • 內(nèi)存查看Dart vm 信息展示當(dāng)前 Dart 內(nèi)存使用情況具體類信息所占用的空間跟數(shù)量類屬性和方法展示
  • CPU 模塊CPU 詳細(xì)信息展示CPU 是使用率(iOS)App 內(nèi)存和磁盤使用情況
  • 性能看板GPU 和 UI FPS 信息展示
  • 顏色吸管顏色值獲取十六進(jìn)制
  • 對(duì)齊標(biāo)尺widget 屏幕坐標(biāo)展示可自動(dòng)吸附最近 widget
  • 二維碼二維碼生成
  • Logger展示 debugPrint 函數(shù)輸出日志支持搜索
  • Device Info手機(jī)硬件信息展示
  • HTTP Server目前 8080 端口用于上傳文件,用戶可上傳 HAR 文件,用于 Mock 請(qǐng)求8888 端口作為數(shù)據(jù)端口,目前用途是校驗(yàn)服務(wù) host、接收用戶上傳的文件未來計(jì)劃開放更多數(shù)據(jù) api,允許通過該服務(wù)讀取 UME 中的數(shù)據(jù)
  • Channel Monitorchannel 調(diào)用方法名稱請(qǐng)求參數(shù)返回起始時(shí)間返回結(jié)果支持搜索

接下來會(huì)詳細(xì)介紹一些核心功能的使用效果以及核心實(shí)現(xiàn)

模塊詳解

Widget 信息

可以查看當(dāng)前選中 widget 的大小、名稱,文件路徑以及代碼所在行數(shù),有了這工具,即使你不負(fù)責(zé)這個(gè)功能模塊的開發(fā),你也能迅速找到當(dāng)前代碼。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

那如何能獲取到選中當(dāng)前 widget 的信息呢,大小通過RenderObject 就能拿到,那 widget 的代碼位置呢? 通過WidgetInspectorService 中的 getSelectedSummaryWidget 便可以獲取到一個(gè) json 字符串,我們來看下它的結(jié)構(gòu):

{    "description":"Text",    "type":"_ElementDiagnosticableTreeNode",    "style":"dense",    "hasChildren":true,    "allowWrap":false,    "locationId":0,    "creationLocation":{        "file":"file:///Users/.../example/lib/home/widgets/category_card.dart",        "line":69,        "column":15,        "parameterLocations":[            {                "file":null,                "line":70,                "column":24,                "name":"data"            },            ...         ]    },    "createdByLocalProject":true,    "children":[        {            "description":"RichText",            "type":"_ElementDiagnosticableTreeNode",            "style":"dense",            "allowWrap":false,            "locationId":1,            "creationLocation":{                "file":"file://../packages/flutter/lib/src/widgets/text.dart",                "line":425,                "column":21,                "parameterLocations":[                    {                        "file":null,                        "line":426,                        "column":7,                        "name":"textAlign"                    },                   ...                ]            },            "children":[],            "widgetRuntimeType":"RichText",            "stateful":false        }    ],    "widgetRuntimeType":"Text",    "stateful":false}

由于數(shù)據(jù)太多了,省略了一部分, 然后根據(jù)對(duì)應(yīng)的 key 即可找到需要的部分。

Widget 層級(jí)

可以查看當(dāng)前選中 widget 的樹層級(jí),以及它 renderObject 的詳細(xì) build 鏈。

UME - 豐富的Flutter調(diào)試工具(flutter uri)UME - 豐富的Flutter調(diào)試工具(flutter uri)

這個(gè)獲取到選中 widget 的一個(gè) build 鏈還是比較簡單的,通過 InspectorSelection 獲取到當(dāng)前 currentElement ,然后 使用 debugGetDiagnosticChain 方法就可以獲取到整個(gè) build 鏈了。

RenderObject 的信息也很好得到,通過currentElement 拿到 當(dāng)前的RenderObject,然后使用 toString方法就可以拿到了。

ShowCode

可以查看到當(dāng)前頁面的頁面代碼。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

主要實(shí)現(xiàn)涉及到以下幾個(gè)關(guān)鍵點(diǎn):

  1. 獲取到當(dāng)前頁面 widget 所屬的文件名
  2. 根據(jù) dart 腳本的文件名來找到并讀取腳本

獲取文件名主要利用WidgetInspectorService實(shí)現(xiàn)。

而讀取腳本主要使用VMService實(shí)現(xiàn)。

獲取當(dāng)前頁面 widget 文件名

  • 我們通過遍歷獲得當(dāng)前頁面的renderObject列表,按照大小篩選出我們想要的目標(biāo) widget。
  • Widget 信息中講解到過,我們可以通過WidgetInspectorServicegetSelectedSummaryWidget 方法獲取到 json 字符串。
  • 提取"creationLocation"的值即是當(dāng)前 widget 的在開發(fā)過程中的文件地址。
  • 我們截取出來地址字符串的最后一部分就是當(dāng)前頁面代碼所在的文件名了。

找到并讀取腳本

  • VMService中的getScripts方法可以獲取當(dāng)前線程下的所有庫文件的 ID 和文件名。
  • 我們通過比對(duì)文件名可以獲得目標(biāo)庫文件 id。
  • 通過VMServicegetObject方法可以獲取到當(dāng)前 id 對(duì)應(yīng)的對(duì)象,我們傳入剛剛獲取的庫文件 id 即可獲得這個(gè)庫對(duì)象,讀取對(duì)象的source屬性,里面就是我們的源碼了。

內(nèi)存泄露

LeakDetector 用于檢測 flutter 內(nèi)存泄漏,總體的實(shí)現(xiàn)思想和 Android 平臺(tái)的LeakCannary工具類似。利用Expando來弱引用持有待檢測對(duì)象,并且使用 VMService 拿到泄漏對(duì)象的引用鏈,最終將泄漏信息本地存儲(chǔ)并且展示出來。

UME - 豐富的Flutter調(diào)試工具(flutter uri)UME - 豐富的Flutter調(diào)試工具(flutter uri)

Dart VM Service Dart 提供的一套 web 服務(wù),數(shù)據(jù)傳輸協(xié)議是 JSON-RPC 2.0。通過它提供的接口我們能獲取到 Dart 虛擬機(jī)內(nèi)部的一些重要信息。下面介紹下整個(gè)過程:

  1. 獲取 VMService 服務(wù)
  • 獲取 ObservatoryUri通過Service.“getInfo“()獲取ServiceProtocolInfo,從中取出serverUri通過vm_service中的 util 工具方法convertToWebSocketUrl()將上面的 http 格式的 uri 格式轉(zhuǎn)為 ws://格式獲取 VmService 服務(wù)對(duì)象, vm_service_io文件中有個(gè)vmServiceConnectUri()方法,傳入一個(gè)observatoryUri就可以獲取一個(gè) VmService 對(duì)象
  1. 獲取 isolateId
  • 通過 VmService 的 getVM 方法拿到 VM 對(duì)象,VM 對(duì)象中存儲(chǔ)著所有的 IsolateRef通過Service.getIsolateID(Isolate.current)拿到,只有 debug 下有效,release 下會(huì)返回 null
  1. 獲取 libraryId
  • 通過第 2 步拿到 isolateId 之后,然后調(diào)用 VmService 的getIsolate拿到對(duì)應(yīng)的 Isolate 對(duì)象。
  • 遍歷 Isolate 的 libraries 字段,這是一個(gè) LibraryRef 的 List,然后拿當(dāng)前 Library 的 uri 去 List 中匹配 LibraryRef 的 uri,就可以獲取 LibraryRef 的 id。
  • 拿著 isolateId 和 LibraryRef 的 Id,調(diào)用 VmService 的 getObject 方法就可以獲取 Library,取其 id 字段就是我們要找的 libraryId(其實(shí) LibraryRef 的 id 應(yīng)該就是了,實(shí)際可以測試)。
  1. 獲取 objectId

由于getInstance(isolateId, classId, limit)方法存在性能和 limit 限制的問題,我們轉(zhuǎn)而利用invoke(isolateId, targetId, selector, argumentIds, disableBreakpoints)方法,借助 Library 頂層函數(shù)就可以獲取 libraryId 也就是 invoke 方法中的 targetId,最后我們只需要將目標(biāo)對(duì)象暫存一下再通過 invoke 方法取出來就可以拿到該對(duì)象的 InstanceRef 了,進(jìn)而拿到其 id 字段就是我們要找的 objectId 了。

  1. 泄漏判斷
  • 通過 getObject(isolateId, objectId)方法拿到 Expando 的對(duì)象的 Obj 實(shí)例,它的真實(shí)類型其實(shí)是一個(gè) Instance。
  • 遍歷 Instance 的 fields 字段找到_data(_data 的類型是 ObjRef,可以拿到它對(duì)應(yīng)的 Instance 實(shí)例)字段(怎么找_data?可以通過 BoundField 的 FieldRef 字段,然后匹配 FieldRef 的 name 為‘_data’),在expando_path.dart中我們可以看到 Expando 的具體實(shí)現(xiàn),_data 字段是一個(gè) List。
  • 遍歷_data 字段,如果都為 null,表明我們觀察的 key 對(duì)象都釋放了;如果元素不為 null,則將該該元素轉(zhuǎn)為 Instance 對(duì)象(其實(shí)就是一個(gè) WeakProperty),取其 propertyKey 字段就是我們實(shí)際的沒被回收的對(duì)象了。
  1. 獲取引用路徑
  • VmService 有一個(gè)getRetainingPath方法可以直接拿到一個(gè)對(duì)象的引用鏈,但是只會(huì)拿一條。
  • 需要注意在前面使用 Expando 檢測完內(nèi)存泄漏之后,就釋放 Expando 對(duì)原始對(duì)象的引用。
  • Instance 的 id 會(huì)過期,VmService 對(duì)它的緩存最大是 8192,所以不要保存 id 而要保存對(duì)象。
  1. 觸發(fā) GC
  • VmService 有一個(gè)getAllocationProfile(isolateId, gc=true)方法,通過它來觸發(fā) dart vm 進(jìn)行 gc,這個(gè)也是 Dev Tools 工具上觸發(fā) gc 按鈕最終調(diào)用的方法。據(jù)測試觸發(fā)的都是 FULL GC。
  1. 觸發(fā)時(shí)機(jī)
  • Route 檢測借助 framework 提供的NavigatorObserver機(jī)制,可以很輕松的監(jiān)聽到頁面的進(jìn)出棧,在 didPop、didRemove、didReplace 方法中觸發(fā)對(duì) route 的泄漏檢測。
  • Widget/State 檢測一般的頁內(nèi) Widget/State 不檢測,而只檢測真正頁面對(duì)應(yīng)的 Widget 和 State,framework 并沒有提供一個(gè)全局監(jiān)聽頁面銷毀的機(jī)制。這里我們借助hook_annotation(這個(gè)后面會(huì)解釋)來 hook 兩個(gè)點(diǎn):RouteRootState 的 initState 方法,記錄要檢測的頁面對(duì)象;State 的 dispose 方法,如果是我們已記錄的頁面,則觸發(fā)檢測流程。

內(nèi)存查看

Memory 可用于查看當(dāng)前 Dart VM 對(duì)象所占用情況。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

需要拿到 vm 內(nèi)存的話就必須得依賴 Dart VM,上文說到,通過 vm_service 就可通過它提供的接口拿到。

通過 Future<MemoryUsage> getMemoryUsage 就能獲取到當(dāng)前 isolate 所占用的信息,來看下 MemoryUsage 的結(jié)構(gòu), 每個(gè)屬性都有詳細(xì)的解釋,這里就不再贅述了。

/// The amount of non-Dart memory that is retained by Dart objects. For/// example, memory associated with Dart objects through APIs such as/// Dart_NewWeakPersistentHandle and Dart_NewExternalTypedData.  This usage is/// only as accurate as the values supplied to these APIs from the VM embedder/// or native extensions. This external memory applies GC pressure, but is/// separate from heapUsage and heapCapacity.int externalUsage;/// The total capacity of the heap in bytes. This is the amount of memory used/// by the Dart heap from the perspective of the operating system.int heapCapacity;/// The current heap memory usage in bytes. Heap usage is always less than or/// equal to the heap capacity.int heapUsage;

那如何獲取到每個(gè)類對(duì)象的內(nèi)存信息呢?

通過 getAllocationProfile 獲取分配對(duì)象的信息,通過members屬性來獲取到每個(gè) class 所占用的堆信息。

對(duì)齊標(biāo)尺

對(duì)齊標(biāo)尺用來測量當(dāng)前 widget 所在屏幕的一個(gè)坐標(biāo)位置,開啟吸附開關(guān)后可以自動(dòng)吸附最近 widget。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

標(biāo)尺顯示當(dāng)前坐標(biāo)還是非常簡單的,通過手勢移動(dòng)的坐標(biāo),來改變Positioned的位置即可,并通過屏幕的大小來計(jì)算出當(dāng)前的距離,下面會(huì)著重講一下自動(dòng)吸附的實(shí)現(xiàn)。

要吸附最近的 widget,就必須找到當(dāng)前位置的所在的 widget,然后并畫出當(dāng)前 widget 的一個(gè)大小范圍,最后設(shè)置標(biāo)尺的位置即可,那么如何找到當(dāng)前坐標(biāo)的 widget 呢?

通過 globalKey 我們可以獲取到當(dāng)前頁面的一個(gè)RenderObject,然后通過它的debugDescribeChildren 獲取到它的所有子節(jié)點(diǎn),然后通過describeApproximatePaintClip獲取到當(dāng)前對(duì)象坐標(biāo)系中的Rect,之后在根據(jù)一些坐標(biāo)轉(zhuǎn)換,判斷是不是在當(dāng)前坐標(biāo)范圍,最后根據(jù)RenderObject 的大小做一個(gè)排序,這樣我們就能知道最小的那個(gè)一定是當(dāng)前坐標(biāo)位置中最近的 widget 了,得到最近的 widget 之后,我們只需要將標(biāo)尺的中心位置設(shè)置成離 widget 最近的四個(gè)角即可。

顏色吸管

可以查看到當(dāng)前頁面任何像素的顏色,方便調(diào)試 UI。

UME - 豐富的Flutter調(diào)試工具(flutter uri)

這個(gè)功能首先分為兩步,1、背景放大 2、獲取當(dāng)前像素的顏色值

如何放大圖片

在 Flutter 中,要想給圖片加一些效果,我們可以用到 BackdropFilter, 其實(shí)就是加上一層濾鏡效果,發(fā)現(xiàn)參數(shù)其實(shí)并不多,通過 ImageFilter就能添加具體的濾鏡,想要做一個(gè)放大的效果,我們可以使用 ImageFilter.matrix ,它能夠放大背景圖片, filterQuality 參數(shù)可以用來設(shè)置放大效果的質(zhì)量,那如何放大對(duì)應(yīng)的位置以及放大的倍數(shù)呢?

通過Matrix4便可以設(shè)置,通過我們手勢移動(dòng)的位置,加上 scale 就能計(jì)算出它的矩陣參數(shù),并賦值給ImageFilter.matrix就能得到放大效果。

如何獲取圖片像素及顏色值

在 Flutter 中想要截圖的話就必須借助RepaintBoundary了,配合globalKey我們就能獲取當(dāng)屏幕的當(dāng)前截圖了。

RenderRepaintBoundary boundary = rootKey.currentContext.findRenderObject();Image image = await boundary.toImage();ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);Uint8List pngBytes = byteData.buffer.asUint8List();snapshot = img.decodeImage(pngBytes);

獲取到截圖后,我們就需要通過移動(dòng)的位置來獲取到圖片的當(dāng)前像素值了,可以通過ImagegetPixelSafe 來獲取到 用 Uint32 編碼過的像素顏色值了(#AABBGGRR),最后我們只需要把abgr轉(zhuǎn)換成 argb 就好了。

int abgrToArgb(int argbColor) {  int r = (argbColor >> 16) & 0xFF;  int b = argbColor & 0xFF;  return (argbColor & 0xFF00FF00) | (b << 16) | r;}

網(wǎng)絡(luò)調(diào)試

在調(diào)試 Flutter 網(wǎng)絡(luò)的時(shí)候,要 mock 數(shù)據(jù)或者查看請(qǐng)求非常麻煩,需要連代理,使用抓包工具才可以進(jìn)行這些操作,想要簡單的在手機(jī)上就能完成這些操作,所以網(wǎng)絡(luò)調(diào)試模塊目前支持的功能:

  • 支持所有網(wǎng)絡(luò)請(qǐng)求抓取
  • 數(shù)據(jù)支持結(jié)構(gòu)化展示,長按可以復(fù)制到剪貼板
  • 收藏請(qǐng)求,單獨(dú)展示;清空非收藏列表
  • 請(qǐng)求過濾與搜索(支持部分匹配、正則匹配)
  • 請(qǐng)求導(dǎo)出 curl
  • 持久化與導(dǎo)出 HAR
  • mock 響應(yīng)內(nèi)容完整 har 文件映射修改單個(gè)字段
  • 結(jié)構(gòu)化信息長按復(fù)制

UME - 豐富的Flutter調(diào)試工具(flutter uri)UME - 豐富的Flutter調(diào)試工具(flutter uri)UME - 豐富的Flutter調(diào)試工具(flutter uri)

?

?

看到這,你可能會(huì)問這是怎么攔截到所有的網(wǎng)絡(luò)請(qǐng)求的呢?

這里通過 Dart 在編譯時(shí)的插樁從而達(dá)到對(duì)特定 API 的 hook 效果(其實(shí)就是替換掉某個(gè)方法的實(shí)現(xiàn)從而添加自己的實(shí)現(xiàn)),由于篇幅問題,這里暫時(shí)不展開講 Hook 的具體流程~ 之后也會(huì)有另外的文章來詳細(xì)說這個(gè)。

Flutter 中的所有網(wǎng)絡(luò)請(qǐng)求走的都是 package:http/src/base_client.dartBaseClient 類中的_sendUnstreamed, 因此,我們只需要 hook _sendUnstreamed 方法便可以攔截到所有的網(wǎng)絡(luò)請(qǐng)求。

Logger

會(huì)展示使用 debugprint 函數(shù)打印的日志,特別是播放器的一些日志,在沒有 IDE 的情況下,查看日志還是很方便的。 ?

UME - 豐富的Flutter調(diào)試工具(flutter uri)

攔截 print 有兩種方式:

  • Dart 中有一個(gè)runZoned方法,可以給執(zhí)行對(duì)象指定一個(gè) Zone,Zone 表示一個(gè)代碼執(zhí)行的環(huán)境范圍,Zone 類似一個(gè)代碼執(zhí)行沙箱,不同沙箱的之間是隔離的,沙箱可以捕獲、攔截或修改一些代碼行為,如 Zone 中可以捕獲日志輸出、Timer 創(chuàng)建、微任務(wù)調(diào)度的行為,同時(shí) Zone 也可以捕獲所有未處理的異常。runZoned(…)方法定義:

R runZoned<R>(R body(), {    Map zoneValues,     ZoneSpecification zoneSpecification,    Function onError}) zoneValues: Zone 的私有數(shù)據(jù),可以通過實(shí)例zone[key]獲取

zoneSpecification:Zone 的一些配置,可以自定義一些代碼行為,比如攔截日志輸出行為等。

這樣所有調(diào)用 print 方法輸出日志的行為都會(huì)被攔截。

runZoned(() => runApp(MyApp()), zoneSpecification: new ZoneSpecification(    print: (Zone self, ZoneDelegate parent, Zone zone, String line) {      print(line);}));

  • 通 hook 的方式

由于在 hook 的 print 方法里可能會(huì)調(diào)用 print 來打印日志造成死循環(huán),這里我們只 hook debugPrint 方法,對(duì) package:flutter/src/foundation/print.dartdebugPrintThrottled 進(jìn)行 hook 即可。

Channel Monitor

可以查看到所有的 channel 調(diào)用,包括方法名,時(shí)間,參數(shù),返回結(jié)果。 ?

UME - 豐富的Flutter調(diào)試工具(flutter uri)UME - 豐富的Flutter調(diào)試工具(flutter uri)

?

hook package:flutter/src/services/platform_channel.dartMethodChannel 類的invokeMethod方法即可。

目前存在的問題

目前只是完成了初步的版本,很多功能還需要繼續(xù)完善以及更多的新功能;接下來會(huì)從一些細(xì)節(jié)上繼續(xù)深入;現(xiàn)在網(wǎng)絡(luò)調(diào)試、channel 監(jiān)控、Logger 這些功能依賴于 Hook 方案,后續(xù) hook 方案也會(huì)考慮開源。

總結(jié)

以上介紹了一些 UME 的核心功能以及實(shí)現(xiàn),還有很多豐富的功能由于篇幅問題在這里就不繼續(xù)展開了,之后還會(huì)有更多有趣的東西出現(xiàn),未來會(huì)考慮開源一些核心功能。

加入我們

我們是負(fù)責(zé)西瓜視頻客戶端 Flutter 基礎(chǔ)技術(shù)研發(fā)團(tuán)隊(duì)。我們在 Flutter 工程,研發(fā)工具等方向深耕,支撐業(yè)務(wù)快速迭代的同時(shí),提高 Flutter 開發(fā)調(diào)式打包效率。

如果你對(duì)技術(shù)充滿熱情,歡迎加入西瓜視頻 Flutter 基礎(chǔ)技術(shù)團(tuán)隊(duì)或者西瓜基礎(chǔ)業(yè)務(wù)團(tuán)隊(duì)。目前我們在上海、北京、杭州、均有招聘需求,內(nèi)推可以聯(lián)系郵箱:tech@bytedance.com ;郵件標(biāo)題:姓名 – 工作年限 – 西瓜 – iOS/Android。

更多分享

一例 Go 編譯器代碼優(yōu)化 bug 定位和修復(fù)解析

字節(jié)跳動(dòng)破局聯(lián)邦學(xué)習(xí):開源Fedlearner框架,廣告投放增效209%

抖音品質(zhì)建設(shè) – iOS啟動(dòng)優(yōu)化《原理篇》

iOS性能優(yōu)化實(shí)踐:頭條抖音如何實(shí)現(xiàn)OOM崩潰率下降50%


歡迎關(guān)注「 字節(jié)跳動(dòng)技術(shù)團(tuán)隊(duì)

簡歷投遞聯(lián)系郵箱「 tech@bytedance.com

相關(guān)新聞

聯(lián)系我們
聯(lián)系我們
公眾號(hào)
公眾號(hào)
在線咨詢
分享本頁
返回頂部
齐齐哈尔市| 高唐县| 汉中市| 安国市| 舒兰市| 噶尔县| 灵宝市| 浦东新区| 宜川县| 宕昌县| 三江| 灵川县| 清水县| 仁化县| 房产| 鄱阳县| 缙云县| 辰溪县| 内黄县| 垣曲县| 仙游县| 武清区| 阿图什市| 海城市| 元氏县| 西盟| 云安县| 交口县| 隆化县| 临湘市| 城口县| 荔浦县| 淮北市| 鲁山县| 鹿泉市| 泗阳县| 东丽区| 景东| 台南市| 南宫市| 富民县|