tree: 55c58d615e6a45fbf559c29f60703060dfac7dd6
  1. app/
  2. metrics/
  3. src/
  4. Android.bp
  5. AndroidManifest.xml
  6. AppMemoryTest.xml
  7. generate_java_sources.sh
  8. generate_resources.sh
  9. OWNERS
  10. perfetto.textproto
  11. README.md
tests/AppMemoryTest/README.md

AppMemoryTest (smoldroid)

AppMemoryTest is a test designed to produce low-noise, highly-actionable metrics for Android cold app startups. It starts a barebones Android app, then collects and reports only reproducible and easily-attributable metrics, such as the size and number of items on the app heap or total number of binder transactions emitted by the app process.

This guide provides instructions on how to run AppMemoryTest on a local device and in ABTD, as well as how to analyze output artifacts.

Running smoldroid on a local device

  1. Connect a device over ADB (a local physical device, a virtual acloud device, etc.)
  2. From the root of your Android checkout, run source build/envsetup.sh and lunch <target>, e.g. lunch cheetah-trunk_staging-userdebug.
  3. Run atest AppMemoryTestCases, which will output a few metrics in plain text as well as a path to the directory containing atest output artifacts. In the example below, appmemorytest_app_heap_count and appmemorytest_app_heap_size_bytes are the metric results. /tmp/atest_result/20251222_190845_6fbp6fde will contain a Perfetto trace and a .hprof
$ atest AppMemoryTestCases

Atest results and logs directory: /tmp/atest_result/20251222_190845_6fbp6fde

...

arm64-v8a AppMemoryTestCases
----------------------------
arm64-v8a AppMemoryTestCases (1 Test)
[1/1] android.app.memory.tests.AppMemoryTest#testApp: PASSED (12.138s)
        appmemorytest_app_heap_count: 14198
        appmemorytest_app_heap_size_bytes: 563401

...

Googlers can find more detailed steps at go/smoldroid.

Understanding smoldroid metrics

The plain metrics returned after the atest invocation (_heap_count and _heap_size_bytes) refer to the number and size of the objects contained on the barebones test app‘s Java heap after a cold startup. This is directly computed from the .hprof file collected during the test, which can be further inspected with AHAT. The heap object count and size is expected to be fairly stable across test runs, as allocations made during an app startup shouldn’t vary much.

The trace file collected by smoldroid can be analyzed like any other device-side performance trace, meaning that it can be opened in the Perfetto UI and supports PerfettoSQL queries. The metrics/ folder contains a couple of quick sample queries--for example, the SQL in appmemorytest_binder_transactions.textproto can be used to view the full set of binder transactions initiated by the test app during startup.

INCLUDE PERFETTO MODULE android.binder;
INCLUDE PERFETTO MODULE android.startup.startups;
WITH
  testhelper_startup AS (
    SELECT
      ts,
      (ts + dur) AS ts_end
    FROM
      android_startups
    WHERE
      package = 'android.app.memory.testhelper'
    LIMIT 1
  )
SELECT
  abt.aidl_name,
  COALESCE(abt.aidl_name, 'NULL') AS aidl_name_including_nulls
FROM
  android_binder_txns AS abt
  JOIN testhelper_startup
    ON (
      abt.client_ts >= testhelper_startup.ts
      AND abt.client_ts < testhelper_startup.ts_end
    )
WHERE
  abt.client_process = 'android.app.memory.testhelper'

The query above returns this output:

aidl_nameaidl_name_including_nulls
nullNULL
nullNULL
AIDL::java::IActivityManager::attachApplication::serverAIDL::java::IActivityManager::attachApplication::server
nullNULL
AIDL::java::IDisplayManager::getPreferredWideGamutColorSpaceId::serverAIDL::java::IDisplayManager::getPreferredWideGamutColorSpaceId::server
AIDL::java::IDisplayManager::getOverlaySupport::serverAIDL::java::IDisplayManager::getOverlaySupport::server
AIDL::java::IDisplayManager::getDisplayInfo::serverAIDL::java::IDisplayManager::getDisplayInfo::server
AIDL::java::INetworkManagementService::setUidCleartextNetworkPolicy::serverAIDL::java::INetworkManagementService::setUidCleartextNetworkPolicy::server
......