Mobile Development 6 min read

Optimizing Android Class Loading and Verification to Reduce Cold Start Latency

This article analyzes Android's class loading and verification process, identifies optimization opportunities to speed up cold starts, compares industry approaches, and presents a semi‑automated analysis tool along with practical solutions for handling verification failures in mobile apps.

ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
ByteDance Dali Intelligent Technology Team
Optimizing Android Class Loading and Verification to Reduce Cold Start Latency

Introduction: To accelerate application cold start without heavy business changes, this article identifies optimization points in the virtual machine class loading process, compares with industry solutions, and implements a semi‑automated analysis tool.

Class Loading: DefineClass loads a class via SetupClass, InsertClass, and LoadClass, ultimately returning a mirror:Class pointer. SetupClass sets access flags and ClassLoader; InsertClass adds the class to the ClassTable; LoadClass loads fields and methods.

Class Initialization: Before use, a class must be initialized. InitializeClass verifies the class, initializes super‑classes, interfaces, and static fields. VerifyClass checks class legality, detailed later.

Class Verification: VerifyClass uses either VerifyClassUsingOatFile or PerformClassVerification. VerifyClassUsingOatFile checks the class status bit in the OAT file; if it equals kStatusVerified, verification ends quickly, otherwise PerformClassVerification runs, which includes steps such as ComputeWidthsAndCountOps, ScanTryCatchBlocks, VerifyInstructions, and VerifyCodeFlow.

Early Detection: The goal is to keep verification on the fast VerifyClassUsingOatFile path. Using the oatdump command one can inspect the class status bits in an odex file. VLOG output is disabled by default and can be enabled by setting art::gLogVerbosity.class_linker = true . The author used ptrace to inject a custom .so into Zygote for debugging.

Solution: Set the Runtime object's verify_ field to verifier::VerifyMode::kNone . This requires locating the verify_ attribute via the Runtime object's base address, which may cause compatibility issues, missing verification, or increased COW memory usage. Additional steps include removing the EnsureSkipAccessChecksMethods pass and adjusting method flags, which can unintentionally modify all methods.

Case Study: In an Android 8.1 (API 27) environment, TextView lacks setFirstBaselineToTopHeight, causing illegal instructions and verification failure in the AppCompat library. Various workarounds were explored, including recompiling the SDK with a fixed SDK_INT, modifying AppCompat source, and finally creating an ASM plugin to force Build.VERSION.SDK_INT to 27, reducing APK size by 22 KB.

Platformization: To simplify deployment, the solution has been packaged into a web‑based platform where dropping an APK reveals verification failures.

mobile developmentPerformanceAndroidCold StartClass LoadingVerification
ByteDance Dali Intelligent Technology Team
Written by

ByteDance Dali Intelligent Technology Team

Technical practice sharing from the ByteDance Dali Intelligent Technology Team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.