谈谈项目中的内存泄露

本文详细解析了Android中常见的五种内存泄露场景,包括Looper、Activity与长生命周期对象交互、静态接口引用、内部类与匿名内部类以及Fragment的使用不当。针对这些问题,提出了相应的解决策略,强调了避免内存泄露的关键在于防止长生命周期对象持有短生命周期对象。同时,提醒开发者在编码时要提高警惕,避免这类问题的发生。


前言

所举实例,皆为项目中实际遇到,如有描述错误,欢迎评论指正,感谢


提示:以下是本篇文章正文内容,下面案例可供参考

一、Looper 导致内存泄露

描述:
BaseActivity 有个线程,内部实现了 Looper.prepare(); … Looper.loop(); 因为其内部是个死循环,而且还持有子activity引用,
解决:
destroy时调用 该子线程 所持有loop 的quit方法

二、Activity 传给长生命周期对象

描述:
在activity中 尽量不要把this 传给其他对象,特别是第三方框架,因为不知道其内部如何引用,检查的时候也比较困难。
解决:
长生命周期对象 如单例 传Application , 因为传Application 是跟随app的生命周期的,app一退出,所有内存也烟消云散。

三、实例化其他类的静态接口

描述:
比如A(Activity或Fragment)类内部 实例化了一个B类的静态接口,该接口会持有B 对象的引用,导致A 对象不可被回收.
解决:
在A(Activity或Fragment) 退出时,手动将该接口置空 如 B.callback = null

四、内部类和匿名内部类

描述:
不论是内部类还是匿名内部类 都默认持有外部类的引用,有时候需要将 实例化它类的接口,和一些广播接收器 传给外部,外部就间接持有了该类。注意:此处外部是长生命周期对象
解决:
在(Activity或Fragment)退出时,手动将外部所引用的接口或回调置空,注意外部类使用这些东西时尽量做些判空操作。

五、Fragment 中 addFragment

描述:
后者(被addFragment 的 Fragment)会生命周期会跟随前者依附的activity 变化,就是 前者退出时 会回调onDestroy,而在其内部add的fragment 则不会回调onDestroy!!! 注意:后者内部有耗时操作,切在其onDestory 中释放资源
解决:
这也不全算内存泄露,因为如果是在MainActivity 此时就算内存泄露,如果是其他activity 在你退出时,那个fragment 也会随之销毁,内存也随之被回收。


总结

1.内存泄露就一句话,长生命周期对象持有短生命周期对象,造成内存不可被回收。

2.上面没写Handler 导致内存泄露,是因为 在项目中真不是那么容易写出来的,写Android 听过最多的就是 Handler 导致内存泄露,就算写出来 编译器 也给你报一片黄,这个应该是每个安卓开发者都会留意的地方
3.出现问题往往是使我们放松警惕的地方,其实编码中稍加留意,上面问题都是可以避免,

最后祝大家写代码永远没有bug。

你浸淫于程序的迷城,坚持心中的梦想。关心你的朋友,只能在城外锣鼓喧天摇旗呐喊,其实你只需要静谧的私人空间。世人需要娱乐,你开发出游戏。世人需要朋友,你做出交友网站。世人需要聊天,你编写出两只企鹅。你就是网络上最可爱的人,向你致敬!程序员

<think>好的,我现在要回答关于C++中多态的问题。首先,我需要回顾多态的基本概念和它在C++中的实现方式。多态是面向对象编程的三大特性之一,另外两个是封装和继承。多态允许不同类的对象对同一消息做出响应,即同一个方法调用根据对象的不同类型有不同的行为。 接下来,我需要确定用户的问题“谈谈多态”具体需要哪些方面的内容。用户可能希望了解多态的定义、实现方式、虚函数的作用、动态绑定以及实际应用例子等。因此,我需要覆盖这些方面,确保回答全面。 首先,解释多态的基本概念,分为编译时多态和运行时多态。编译时多态包括函数重载和运算符重载,而运行时多态则通过虚函数和继承实现。这里需要详细说明虚函数的作用机制,比如虚函数表(vtable)和虚函数指针(vptr),以及动态绑定的过程。 然后,给出一个具体的代码示例,展示如何通过基类指针调用派生类的重写函数。代码中需要基类声明虚函数,派生类覆盖该虚函数,然后通过基类指针指向派生类对象,调用虚函数时实际执行的是派生类的方法。这能直观地展示运行时多态的效果。 同时,需要提到纯虚函数和抽象基类,说明它们如何强制派生类实现特定接口,从而支持多态。此外,虚析构函数的重要性也不可忽视,确保通过基类指针删除派生类对象时能正确调用派生类的析构函数,避免内存泄漏。 在解释过程中,要确保术语准确,比如区分覆盖(override)和隐藏(hide),说明override关键字的作用,以及C++11之后的相关特性。同时,要指出多态带来的好处,如代码的可扩展性和可维护性,以及可能的性能开销,比如虚函数调用需要通过虚表间接寻址,可能影响性能。 最后,根据用户的指示,生成四个相关问题,这些问题应该涵盖多态的不同方面,如定义、虚函数、纯虚函数、虚析构函数的原因等,确保问题之间有逻辑关联,帮助用户进一步深入学习。 现在需要检查是否有遗漏的关键点,例如动态绑定与静态绑定的区别,或者多态在实际项目中的应用场景。确保回答结构清晰,先总述多态,再分点详细解释,最后代码示例和相关问题。避免使用过于复杂的术语,保持解释简洁明了,适合不同层次的学习者理解。</think><< 多态是面向对象编程中允许不同对象对同一操作表现出不同行为的特性。在C++中主要通过虚函数和继承实现,分为编译时多态(静态绑定)和运行时多态(动态绑定)。 ### 多态的实现方式: 1. **虚函数(Virtual Functions)** 在基类中用 `virtual` 关键字声明函数,派生类可以重写(override)该函数。通过基类指针或引用调用时,会根据实际对象类型执行对应的函数。 ```cpp class Animal { public: virtual void speak() { cout << "Animal sound" << endl; } }; class Dog : public Animal { public: void speak() override { cout << "Woof!" << endl; } // 重写基类虚函数 }; ``` 2. **纯虚函数(Pure Virtual Functions)** 基类声明未实现的虚函数(用 `= 0` 标记),强制派生类必须实现。包含纯虚函数的类称为抽象类,不能实例化。 ```cpp class Shape { public: virtual double area() = 0; // 纯虚函数 }; ``` 3. **动态绑定(Dynamic Binding)** 运行时根据对象类型确定调用哪个函数。通过虚函数表(vtable)和虚指针(vptr)实现。 4. **虚析构函数(Virtual Destructor)** 确保通过基类指针删除派生类对象时,能正确调用派生类的析构函数: ```cpp class Base { public: virtual ~Base() {} // 虚析构函数 }; class Derived : public Base { public: ~Derived() { /* 清理派生类资源 */ } }; ``` ### 示例代码: ```cpp #include <iostream> using namespace std; class Animal { public: virtual void speak() { cout << "Animal sound" << endl; } virtual ~Animal() = default; // 虚析构函数 }; class Dog : public Animal { public: void speak() override { cout << "Woof!" << endl; } }; class Cat : public Animal { public: void speak() override { cout << "Meow!" << endl; } }; int main() { Animal* animals[] = {new Dog(), new Cat()}; for (auto* animal : animals) { animal->speak(); // 输出 Woof! Meow! delete animal; } return 0; } ``` ### 关键点: - **编译时多态**:如函数重载、模板,在编译期确定调用。 - **运行时多态**:通过虚函数动态绑定,需运行时类型信息(RTTI)。 - **override关键字**(C++11):明确表示重写,避免意外隐藏(hide)基类函数。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值