オリジナルの記事は、ソースを明記してください、ありがとうございました!
CPU周波数、スケジューリングおよびコンパイラのフィルタはすべて除外されている場合は、何も問題ありません。それは、特定の方法で時間がかかるがあるかどうかを見てください。
一般的に使用される分析ツール:
1.systraceは、
本明細書できるSYSTRACEもちろん、ホットとコールドスタート点があり、比較分析によって様々な段階片。
:次のようにいくつかのコールドスタート段階では解決することができ
INPUT /プロセスを提供するフォーク/バインド・ファイルアプリケーション/活動スタート/ doFrame / drawFrame / SF&無効リフレッシュ
描き、主な考慮事項をレンダリングするためのホットスタートを。
違いは、それが特定のメソッドを分析するためにかかる時間であり、特定の地域である場合にギャップが、一定の段階に集中しているかどうかを確認します。
位相差を洗練し、特定の方法の範囲を狭めるために、トレースを追加することによって求めることができます。
プラス層の方法をトレース:
APP:
Trace.beginSection("");
Trace.endSection();
注意:キャッチSYSTRACEは、対応するアプリケーションのプロセスを指定する必要がある場合。
Javaの層システム:
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate”);
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
注意:パラメータは、スイッチグリップSYSTRACEオプションの前にあるタグに対応します。
ネイティブ:
#define ATRACE_TAG ATRACE_TAG_ALWAYS
#include <utils/Trace.h> // for c++
#include <cutils/trace.h> // for c
ATRACE_CALL();
or
ATRACE_BEGIN("");
ATRACE_END();
2. TraceViewまたはASプロファイルCPU
質問アプリの場合は、あなたが助けることができるtraceViewかのように、プロファイルCPUのCPUアクティビティをトラッキング機能をチェックし、時間のかかる方法を見つけやすくするために、問題を特定する範囲を狭めるために続けました。
3.逆コンパイル
三者Appの、何のソースが逆コンパイルのoatdumpによって分析することができません:
adbのシェル-oatdump --oat =ファイル/データ/アプリケーション/パッケージ名/oat/arm64/base.odex> demo.txt
バイトコードコマンドの説明
第二に、実際の例:高い道徳的なマップの時間のかかる分析
1.問題を特定
CPUの周波数では、スケジューリングおよびコンパイラのフィルタは、すべてのSYSTRACE特定の開始時間がかかる場合によって様々な段階を分析するために、前提の外に支配されています。
AndroidのN:
AndroidのO:
私たちは、MapContainer実行時間は、ハイクラスのドイツのMapContainer独自の実装が比較的長く、高いドイツは、Androidの異なるバージョンでの実装は比較的大きな違いである必要がありました。ドイツは、高いパーティ製のアプリケーションを、そこにはコードがないので、traceViewを分析するのに役立つています。
注意:それはコールドスタートの場合はキャプチャするコマンドラインを使用することができます。
1)を同時に起動し、トレース指定の活動を開始
am start -n com.stan.note.newdemo/.MainActivity --start-profiler /data/local/tmp/test.trace
am profile com.stan.note.newdemo stop
2)自動的に、指定された活動と同時に開始トレースを開始し終了
am start -n com.stan.note.newdemo/.MainActivity -P /data/local/tmp/test.trace
TraceViewによって二つの関連法は非常に時間がかかるですが見つかりました:
com.autonavi.mao.core.OverlayManager.init ()V
com.autonavi.minimap.commute.CommuteOverlay.init ()V
oatdumpすることにより、以下の2つのメソッドをコンパイルするには
小さな断片をインターセプト:
void com.autonavi.minimap.commute.CommuteOverlay.init() (dex_method_idx=20281)
DEX CODE:
0x0000: 1202 | const/4 v2, #+0
0x0001: e530 0800 | iget-object-quick v0, v3, // offset@8
0x0003: 7110 6006 0000 | invoke-static {v0}, android.view.LayoutInflater android.view.LayoutInflater.from(android.content.Context) // method@1632
0x0006: 0c00 | move-result-object v0
0x0007: 6001 a235 | sget v1, I com.autonavi.minimap.R$layout.commute_marker_layout // field@13730
0x0009: e930 1200 1002 | invoke-virtual-quick {v0, v1, v2}, // vtable@18
0x000c: 0c00 | move-result-object v0
ここでは芸術がかかり、特定機能するかを決定するために、機能命令と対応するトレースを追加することを探していました。
以下に説明するように例えばSGET手順については、解釈されたコマンドに対応
art/runtime/interpreter/mterp/arm64/op_sget.S
%default { "is_object":"0", "helper":"MterpGet32Static", "extend":"" }
2 /*
3 * General SGET handler wrapper.
4 *
5 * for: sget, sget-object, sget-boolean, sget-byte, sget-char, sget-short
6 */
7 /* op vAA, field//BBBB */
8
9 .extern $helper
10 EXPORT_PC
11 FETCH w0, 1 // w0<- field ref BBBB
12 ldr x1, [xFP, #OFF_FP_METHOD]
13 mov x2, xSELF
14 bl $helper
15 ldr x3, [xSELF, #THREAD_EXCEPTION_OFFSET]
16 lsr w2, wINST, #8 // w2<- AA
17 $extend
18 PREFETCH_INST 2
19 cbnz x3, MterpException // bail out
20.if $is_object
21 SET_VREG_OBJECT w0, w2 // fp[AA]<- w0
22.else
23 SET_VREG w0, w2 // fp[AA]<- w0
24.endif
25 ADVANCE 2
26 GET_INST_OPCODE ip // extract opcode from rINST
27 GOTO_OPCODE ip
このセクションでは、命令のコンパイルで、具体的な手順は時間がかかり、ある確かに時間のかかる機能を実行することではありません。$ヘルパー関数呼び出しはMterpGet32Static機能に対応します。
また対応で機能をトレース
art/runtime/interpreter/mterp/mterp.cc
#include "base/systrace.h"
extern "C" int MterpSet32Static(uint32_t field_idx,
int32_t new_value,
ArtMethod* referrer,
Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
return MterpSetStatic<int32_t, Primitive::kPrimInt>(field_idx,
new_value,
referrer,
self,
&ArtField::SetInt<false>);
}
対応する方法MterpSetStaticプラストレースで。
template <typename return_type, Primitive::Type primitive_type>
ALWAYS_INLINE return_type MterpGetStatic(uint32_t field_idx,
ArtMethod* referrer,
Thread* self,
return_type (ArtField::*func)(ObjPtr<mirror::Object>))
REQUIRES_SHARED(Locks::mutator_lock_) {
ScopedTrace trace(__FUNCTION__);
return_type res = 0; // On exception, the result will be ignored.
ArtField* f =
FindFieldFromCode<StaticPrimitiveRead, false>(field_idx,
referrer,
self,
primitive_type);
if (LIKELY(f != nullptr)) {
ObjPtr<mirror::Object> obj = f->GetDeclaringClass();
res = (f->*func)(obj);
}
return res;
}
問題の2.分析
各DexFileオブジェクトはDexCacheオブジェクトに対応する一方MterpGetStaticは、クラスの静的メンバを得ることである理由85ミリ秒を過ごした?APK DEXファイルに、DexFile対象技術に変換されます。DexCache効果はDEX(タイプ)内のファイルに含まれる情報の種類、方法(方法)、フィールド(フィールド)、ストリング(文字列)と静的な記憶領域(静的記憶)などをキャッシュするために使用されます。
art/runtime/mirror/dex_cache.cc
void DexCache::Init(const DexFile* dex_file,
ObjPtr<String> location,
StringDexCacheType* strings,
uint32_t num_strings,
TypeDexCacheType* resolved_types,
uint32_t num_resolved_types,
MethodDexCacheType* resolved_methods,
uint32_t num_resolved_methods,
FieldDexCacheType* resolved_fields,
uint32_t num_resolved_fields,
MethodTypeDexCacheType* resolved_method_types,
uint32_t num_resolved_method_types,
GcRoot<CallSite>* resolved_call_sites,
uint32_t num_resolved_call_sites)
REQUIRES_SHARED(Locks::mutator_lock_);
上記DexCache初期化関数であり、num_resolved_fieldsこのパラメータについて印刷するDexCacheキャッシュフィールドの数を表します
N:
03-21 15:57:56.409 5982 5982 E art : syh DexCache::Init classes.dex num_resolved_fields 56285
03-21 15:57:56.433 5982 5982 E art : syh DexCache::Init classes.dex num_resolved_fields 25449
03-21 15:57:56.437 5982 5982 E art : syh DexCache::Init classes.dex num_resolved_fields 63062
03-21 15:57:56.569 5982 5982 E art : syh DexCache::Init classes.dex num_resolved_fields 7802
03-21 15:57:56.917 5982 6097 E art : syh DexCache::Init classes.dex num_resolved_fields 115
03-21 15:57:58.088 5982 6032 E art : syh DexCache::Init classes.dex num_resolved_fields 16
03-21 15:57:58.993 5982 6121 E art : syh DexCache::Init classes.dex num_resolved_fields 27
O:
03-17 14:31:41.834 5358 5358 E zygote : syh DexCache::Init classes.dex num_resolved_fields 1024
03-17 14:31:41.854 5358 5358 E zygote : syh DexCache::Init classes.dex num_resolved_fields 1024
03-17 14:31:41.860 5358 5358 E zygote : syh DexCache::Init classes.dex num_resolved_fields 1024
03-17 14:31:42.051 5358 5358 E zygote : syh DexCache::Init classes.dex num_resolved_fields 1024
03-17 14:31:42.302 5358 5436 E zygote : syh DexCache::Init classes.dex num_resolved_fields 279
03-17 14:31:42.448 5358 5469 E zygote : syh DexCache::Init classes.dex num_resolved_fields 115
03-17 14:31:42.914 5358 5541 E zygote : syh DexCache::Init classes.dex num_resolved_fields 16
03-17 14:31:44.516 5358 5492 E zygote : syh DexCache::Init classes.dex num_resolved_fields 27
AndroidのO、1024フィールドまでDexCacheキャッシュでは、実際にはリードMterpGetStaticキャッシュヒット率がMterpGetStatic時間がかかり、その結果、非常に低い場合は、提出された数万人があります。
3.問題を解決
Nはと一致しているキャッシュサイズを調整してみてください、MterpGetStaticが大幅に高速な80ミリ秒のシングルを膨らま改善、最適化の高い道徳的なマップは、166ミリ秒後に起動時間を短縮することができます。
ます。https://www.jianshu.com/p/3ed1938ff75dで再現