LoliProfiler now includes a dedicated CLI executable (LoliProfilerCLI.exe) designed for CI/CD integration and automated testing workflows. This console application allows you to profile Android applications without the GUI, automatically capture memory data, and save results to .loli files for later analysis.
- LoliProfiler.exe - GUI application
- LoliProfilerCLI.exe - Dedicated console application (CLI only, smaller size, better console integration)
- Headless Operation: No GUI required, perfect for CI/CD pipelines
- Automatic Launch & Injection: Automatically starts and injects profiling hooks
- Flexible Capture Modes:
- Timed profiling (fixed duration)
- Manual stop with Ctrl+C (profile until you're ready to stop)
- Graceful Shutdown: Ctrl+C triggers proper data collection and file save
- Symbol Translation: Automatic address-to-symbol translation with symbol files
- Data Optimization: Streaming mode enabled by default for large datasets
- Device Selection: Support for multiple connected Android devices
All options use Qt's standard format: --option value (double dash with space-separated value).
--app <package_name>- Target application package name (e.g.,com.example.game)--out <output_path>- Output.lolifile path
--symbol <symbol_path>- Path to symbol file (.soor.sym) for address translation--subprocess <name>- Target subprocess name (if app uses multiple processes)--device <serial>- Device serial number (required when multiple devices connected)--duration <seconds>- Profiling duration in seconds (omit for manual stop with Ctrl+C)--attach- Attach to running app instead of launching new instance--verbose- Enable verbose output for debugging--helpor-h- Display help message
All other options will use what you set in gui mode.
Profile an app for 60 seconds:
# Using dedicated CLI executable (recommended)
LoliProfilerCLI.exe --app com.example.game --out profile.loli --duration 60Profile with automatic symbol resolution:
LoliProfilerCLI.exe --app com.example.game --out profile.loli \
--symbol /path/to/libgame.so --duration 120Profile until you manually stop (press Ctrl+C when ready):
LoliProfilerCLI.exe --app com.example.game --out profile.loli --verboseWhen you press Ctrl+C:
- The profiler sends a SMAPS_DUMP command to the Android agent
- Memory mapping data is collected
- All data is saved to the
.lolifile - The profiler exits cleanly with proper cleanup
This is useful for:
- Interactive profiling sessions where you control when to stop
- Capturing specific gameplay scenarios
- Ensuring complete memory mapping data is collected before shutdown
Attach to an already-running application (use Ctrl+C to stop when done):
LoliProfilerCLI.exe --app com.example.game --out profile.loli --attachOr with a fixed duration:
LoliProfilerCLI.exe --app com.example.game --out profile.loli \
--attach --duration 30When multiple Android devices are connected:
LoliProfilerCLI.exe --app com.example.game --out profile.loli \
--device emulator-5554 --duration 60Profile a specific subprocess (e.g., for Unity games):
LoliProfilerCLI.exe com.unity.game --subprocess UnityMain \
--out profile.loli --duration 120The CLI mode produces standard .loli files identical to those created by the GUI. These files contain:
- Memory allocation/deallocation records
- Stack traces with symbol information (if provided)
- Memory info timeline (Total, NativeHeap, GfxDev, etc.)
- Screenshots captured during profiling
- SMaps (memory mapping) information
Use --verbose flag to see detailed progress information:
LoliProfilerCLI.exe --app com.example.game --out profile.loli --verboseThis will show:
- Application launch status
- Connection attempts
- Data capture progress
- Symbol translation details
- Save operations
| Feature | GUI Mode | CLI Mode |
|---|---|---|
| User Interface | Full GUI | Console only |
| Device Selection | Interactive dialog | -device flag |
| Duration | Manual stop button | Timed or Ctrl+C |
| Progress | Visual progress bar | Console messages |
| Symbol Loading | File dialog | -symbol flag |
| Data Optimization | User prompt | Always enabled |
| Launch Mode | User prompt | -attach flag |
When you specify --duration <seconds>, the profiler will automatically:
- Profile for exactly the specified duration
- Send SMAPS_DUMP command to collect memory mapping data
- Save all captured data to the output file
- Exit with code 0 on success
When you omit --duration, the profiler runs indefinitely until you press Ctrl+C:
LoliProfilerCLI.exe --app com.example.game --out profile.loli
# Output: "Profiling... Press Ctrl+C to stop."
# ... profile as long as you want ...
# Press Ctrl+C when ready
# Output: "Received stop signal, stopping profiling gracefully..."What happens on Ctrl+C:
- Signal handler catches SIGINT (Ctrl+C) or SIGTERM
- Queues stop request to main thread (thread-safe)
- Sends SMAPS_DUMP command to Android agent
- Collects memory mapping information
- Processes and saves all data to
.lolifile - Exits cleanly with code 0
Important Notes:
- Always use Ctrl+C to stop gracefully - this ensures complete data collection
- Killing the CLI process forcefully (Task Manager,
kill -9) will result in incomplete data - If the app crashes or connection is lost unexpectedly, you'll see an error and data may be incomplete
- The profiler is independent of the app lifecycle - the app can crash/restart and profiling continues
Important: The CLI profiler does NOT automatically stop when the target app exits. This is intentional and matches behavior of professional profiling tools like perf and Android Studio Profiler.
Why?
- Allows profiling across app restarts
- Lets you capture multiple runs in a single session
- Gives you control over exactly when to stop
- Ensures proper data collection with SMAPS_DUMP before shutdown
If the app exits or crashes:
- The profiler will detect connection loss and show an error
- Data captured up to that point is preserved (in cache files)
- You can restart the app and continue profiling
- Use Ctrl+C when you're done to save all data properly
- No real-time visualization (analyze with GUI later)
- Cannot interactively select time ranges (use full capture)
- No manual screenshot triggering (automatic every 5 seconds)
- Requires configured Android SDK/NDK paths
- Windows: Requires properly quoted paths for spaces
The CLI supports comparing two .loli profile files to detect memory regressions between builds or app versions.
LoliProfilerCLI.exe --compare baseline.loli current.loli --out diff.txt--compare <baseline.loli> <current.loli>- Compare two profile files--out <output_path>- Output file (.txtfor text report,.lolifor GUI-viewable format)--skip-root-levels <n>- Skip top N call stack levels (useful for system libs without symbols)
Text format (diff.txt):
=== LoliProfiler Comparison Report ===
Baseline total size: 628.12 MB
Comparison total size: 631.71 MB
Size delta: +3.59 MB
=== Memory Growth (Delta: Comparison - Baseline) ===
FRunnableThreadPThread::Run(), +18.44 MB, +79446
FAsyncLoadingThread::Run(), +9.94 MB, +65478
UDataTable::Serialize(FArchive&), +5.20 MB, +56497
...
Loli format: Can be opened in LoliProfiler GUI for interactive exploration.
For automated analysis of diff or snapshot files, use analyze_heap.py which launches an MCP server and Claude Code to interactively explore heap data and generate detailed reports.
# Analyze a diff
python analyze_heap.py diff.txt --repo /path/to/source -o report.md
# Analyze a heap snapshot
python analyze_heap.py snapshot.txt --repo /path/to/source -o report.md
# HTML output
python analyze_heap.py diff.txt --repo /path/to/source -o report.html
# Different repos for baseline vs comparison
python analyze_heap.py diff.txt --base-repo /path/to/v1 --target-repo /path/to/v2
# Custom minimum size threshold
python analyze_heap.py diff.txt --repo /path/to/source --min-size 1.0Instead of embedding the entire data file into a prompt, analyze_heap.py starts an MCP server that loads the data into an indexed in-memory tree. Claude Code explores the data interactively via tool calls (~10-20KB of context), searches source code, and writes a structured Chinese-language report.
For full details on the MCP tools, interactive mode, and architecture, see MCP Heap Explorer.