Customer Cases
Pricing

How to Find and Fix Memory Leaks in Android Apps (Ultimate Guide)

When the tester tells you that your XXActivity has leaked, how do you confirm whether it has really leaked? After confirming the leak, how do you locate the problem causing the memory leak?

Introduction

When the tester tells you that your XXActivity has leaked, how do you confirm whether it has really leaked?

After confirming the leak, how do you locate the problem causing the memory leak?

In daily Android development, the hardest hit area of memory leaks is Activity. It is believed that these two issues have been encountered by every Android developer. When encountering such problems, we generally use our killer trick: Dump Java Heap and then perform static analysis on the GC chain with MAT. However, today I want to take a different approach and solve this problem from a simpler perspective.

Confirm the leak

First, let's take a look at an abstract Activity pseudocode:

public class LeakActivity extends Activity {

    ComplexLogicA; // Complex business logic code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ComplexLogicB; // Complex business logic code
        LeakLogic; // Business logic code causing the leak
        ComplexLogicC;
        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

        ComplexLogicE;
        ComplexLogicF;
        ComplexLogicG;
    }

    OtherComplexLogin... // Other business logic code
}

 

 

If we want to confirm whether this Activity has a leak, we just need to override the finalize method of the Object and add a Logcat print statement inside:

public class LeakActivity extends Activity {

    ComplexLogicA; // Complex business logic code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ComplexLogicB; // Complex business logic code
        LeakLogic; // Business logic code causing the leak
        ComplexLogicC;
        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

        ComplexLogicE;
        ComplexLogicF;
        ComplexLogicG;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();

        Log.d("", "====LeakActivity has been recycled!");
    }

    OtherComplexLogin... // Other business logic code
}

 

Then run your project, open this Activity, press the back button to exit the Activity, and then force a GC operation through the IDE:

(Android Studio)

(Eclipse)

Next, check the Logcat to see if there is a corresponding print statement. This will confirm whether the Activity has a memory leak: if there is a print statement, there is no memory leak; if there is no print statement, there is definitely a memory leak!

Locate the cause of the leak

Locating the cause of the leak is a relatively simple and crude process of elimination. First, comment out all the complex business logic until the memory leak no longer exists:

public class LeakActivity extends Activity {

//    ComplexLogicA; // Complex business logic code

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

//        ComplexLogicB; // Complex business logic code
//        LeakLogic; // Business logic code causing the leak
//        ComplexLogicC;
//        ComplexLogicD;
    }

    @Override
    protected void onResume() {
        super.onResume();

//        ComplexLogicE;
//        ComplexLogicF;
//        ComplexLogicG;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();

        Log.d("", "====LeakActivity has been recycled!");
    }

//    OtherComplexLogin... // Other business logic code
}

 

Next, enter and exit the Activity again, trigger GC, and confirm that the Activity leak no longer exists. Then, add the business logic back one by one until the leak reappears.

In this way, we can 100% locate the cause of the leak.

Key point

The knowledge point used here is the finalize method in the Object class in Java. When GC is ready to recycle a Java Object (all Java objects are subclasses of Object), GC will call the finalize method of this Object. This method is similar to the destructor in C++, and its original intention is to allow you to recycle some resources that are no longer needed (mainly for native resources). In fact, in daily Java development, it is not encouraged to rely on this method to implement recycling logic, because if you heavily rely on finalize, it may cause memory leaks. However, in our case, it is just used as a basis for whether it has been recycled, which is acceptable.

Conclusion

Although this method may seem simple and crude, it is indeed a convenient self-test method for developers. Without using other tools, you can quickly determine whether the newly added Activity in your current requirements has a leak. Consider it as a way to reduce the number of bugs in your code!

Latest Posts
1How to Reduce Test Leakage: A Complete Guide to Software Testing Quality Test leakage can severely impact software quality. This comprehensive guide covers root causes of test leakage, prevention strategies, testing methods, and effective communication with developers. Learn how to build a robust testing process that catches defects before production.
2Interface Testing: Frontend Interaction vs. Backend Logic Learn interface testing best practices, including frontend interaction testing with mock tools and backend logic testing with comprehensive test case design. Discover how to ensure API quality across testing, staging, and production environments.
3Shifting Trends: These Changes Are Reshaping Mobile App Development Explore the 7 key trends transforming mobile app development, from AI and AR/VR integration to cross-platform frameworks and global localization. Learn how to stay ahead in a shifting digital landscape.
4Full-Link Stress Testing: Solutions, Automation & Professional Services Discover industry-leading full-link stress testing solutions and automation practices. Learn how top enterprises like Lalamove and Bilibili ensure system stability and high availability with WeTest’s professional performance testing services.
5How to Test AI Products: A Complete Guide to Evaluating LLMs, Agents, RAG, and Computer Vision Models A comprehensive guide to AI product testing covering binary classification, object detection, LLM evaluation, RAG systems, AI agents, and document parsing. Includes metrics, code examples, and testing methodologies for real-world AI applications.