Memory analysis
Preparations
You have integrated Memory Analysis as instructed in Android SDK integration.
Product features
1. Add custom dimension data (Optional)
The Memory Analysis SDK provides APIs that you can use to set key-value pairs. These pairs allow you to add custom information to memory analysis logs.
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor
ApmMemMonitor.getInstance().setCustomKey(key, value)
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor;
ApmMemMonitor.getInstance().setCustomKey(key, value);
For more information about the APIs, see Add custom dimensions.
2. Manually trigger memory analysis (Optional)
The Memory Analysis SDK uses internal policies to determine when to trigger an analysis. However, you can call the trigger API to start an analysis as needed.
Memory analysis is triggered only once during each app lifecycle. If an analysis has already been triggered in a lifecycle, calling the manual trigger API does not start another analysis.
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor
ApmMemMonitor.getInstance().triggerMemAnalysis()
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor;
ApmMemMonitor.getInstance().triggerMemAnalysis();
Verify the feature
1. Verify the integration
You can filter logs by the tag:Apm-MemMonitor tag to check if memory analysis is initialized. The following is a key log entry.
I Initializing MemMonitor blocked main for 3 ms
2. Create a memory leak scenario
class LeakActivity: AppCompatActivity () {
companion object {
var activity: Activity? = null
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activity = this
finish()
}
}
public class LeakActivity extends AppCompatActivity {
static Activity activity;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = this;
finish();
}
}
Register LeakActivity in your AndroidManifest.xml file.
3. Manually trigger memory analysis
The Memory Analysis SDK uses internal policies to determine when to trigger an analysis. To quickly verify the feature, you can manually trigger an analysis.
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val memButton = Button(this)
memButton.setText("Test memory analysis")
memButton.setOnClickListener(object : View.OnClickListener {
override fun onClick(view: View?) {
// Trigger memory analysis
ApmMemMonitor.getInstance().triggerMemAnalysis()
}
})
addContentView(
memButton, ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
)
}
import com.aliyun.emas.apm.mem.monitor.ApmMemMonitor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button memButton = new Button(this);
memButton.setText("Test memory analysis");
memButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Trigger memory analysis
ApmMemMonitor.getInstance().triggerMemAnalysis();
}
});
addContentView(memButton, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
}
4. View logs
You can filter logs by the tag:Apm tag:Apm-MemMonitor tags to view the analysis logs. The following are key log entries.
# Successfully triggered memory analysis
I track mem problem, reason=manual trigger mem analysis
# Start memory analysis
D start analysis heap for session=7d08b9cc14054faaaef8f7f81f03122b
I heap analyze step: Extracting metadata
I heap analyze step: Finding retained objects
I heap analyze step: Finding paths to retained objects
I heap analyze step: Finding dominators
I heap analyze step: Inspecting objects
I heap analyze step: Computing native retained size
I heap analyze step: Computing retained size
I heap analyze step: Building leak traces
# Analysis result
D find 1 leaks
D find 0 large objects
# Report result
D report data success. eventId=mem_leak, sessionId=7d08b9cc14054faaaef8f7f81f03122b