oom,内存溢出,分配的内存不够用了导致出错,硬干饭撑死。
ml,内存泄漏,被占用的内存无法得到释放,导致可用内存越来越小,最后可能导致oom,占着茅坑不拉屎。
四大引用。
1:强引用,来时无法回收,全局变量时可赋值为null,jvm合适时会回收,局部变量,引用内容保存在栈中,退出方法栈时,引用内容的引用不存在,回收object
2:软引用,只有内存不足时才回收。
3:弱引用,无论内存够不够,都回收。
4:虚引用,任何时刻都可能被回收,回收时给个通知。
注意:回收的是对象,能不能回收看引用类型,引用类型相当于回收条件,因为我要引用这个对象,我要使用它,你不能说回收就回收,那对引用的工作有影响的。
一:常见的ml->解决方案
1.单例持有context上下文->使用application的contex或使用弱引用,activity回收时那就回收吧,我这个引用也就为null了,不影响activity的销毁,从而回收了内存。
2.handler处理业务时activity可能也就退出了->使用弱引用,判断是否为null,不为null再处理业务。
3.webview->activitiey销毁时及时销毁webview
@Override
protected void onDestroy() {
if (webView != null) {
ViewParent parent = webView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(webView);
}
webView.stopLoading();
webView.getSettings().setJavaScriptEnabled(false);
webView.clearHistory();
webView.removeAllViews();
webView.destroy();
}
super.onDestroy();
}
4.bitmap->bitmap确认不再使用时就释放掉,它占用的内存很大的。
if(bitmap != null && !bitmap.isRecycled()){
bitmap.recycle();
bitmap = null;
}
5.非静态内部类持有外部类的引用比如handler延迟发送信息而activity已经finish->将Handelr声明为静态内部类即放在伴生对象域内
class SecondActivity : AppCompatActivity() {
private val handler = MyHandler(this)
companion object{
class MyHandler(context: Context):Handler(){
private var refence:WeakReference<Context>?= null
//主构造器没有函数体,如果想要在主构造函数中完成初始化,则要用到init关键字
init {
refence = WeakReference(context)
}
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
var activity = refence?.get()
if(activity!=null) {
activity as SecondActivity
if (msg.what == 11) {
activity.jjj.text = "sss"
}
}
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.seconde_activity)
// SingleManager.GetInstance().activityList.add(this)
handler.postDelayed({{}},1*60*100)
finish()
}
}
二:leakcanary的使用
1.添加依赖:debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.3'
2.创建一个单例,引用持有第二个activity
class SingleManager {
private constructor()
public var activityList:ArrayList<Activity> = ArrayList()
companion object{
private var Instance:SingleManager? = null
get() {
if(field==null){
field = SingleManager()
}
return field
}
fun GetInstance():SingleManager{
return Instance!!
}
}
}
MainActivitiy跳转到第二个activity
bt2.setOnClickListener({
startActivity(Intent(this@MainActivity,SecondActivity::class.java))
})
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.seconde_activity)
SingleManager.GetInstance().activityList.add(this)
}
返回后会导致无法释放activity内存造成内存泄漏。
这里就可以看到发生了内存泄漏,源头就是SingleManager
也可以根据leakcanary的目录使用AS 自带的Profiler查看
后面再记录一下leankcanary原理吧。