内存泄漏&&内存溢出
先来看看内存泄漏,内存溢出,OOM,GC回收这几个概念。
把App
的堆内存空间想象成一个杯子,内存就是里面的水。当你的App
启动后,系统会分配给App
一个堆空间,起始不会很大比如是32M
(根据你的App
启动时的内存申请为准)

随着程序的运行对象的创建越来越多,系统不断增加内存分配: 32M ~> 64M ~> ...
而GC
回收则会定时扫描内存,发现不被引用的对象即可回收。正常来说你的App
堆内存会有升有降。此时如果有某个Activity
持有某个引用,在onDestroy
时还不把引用设为null
,那么返回进入退出这个界面,Activity
就会创建很多次从而存在多个实例,导致堆内存直升不降! 这就叫做内存泄漏。
当用户重复这个操作或者有多个不同Activity
内存泄漏时,App
运行一段时间堆内存超过系统规定的最大值heapSize
,杯子满了就会发现出现溢出(OOM)
,App
崩溃。
内存泄漏:
指对象不再使用,本该被回收,却因为有其他正在使用的对象持有该对象的引用,而无法被JVM
回收。
内存泄漏的影响:
a:
应用可用内存减少,增加堆内存压力
b:
频繁触发GC
,会降低应用的性能
c:
到一定程度会导致内存溢出错误
Android开发中常见内存泄漏及解决办法
a: 静态变量生命周期与应用的生命周期一样,如果静态变量持有某个
Activity
的上下文,则对应Activity
无法释放,导致内存泄漏(单例模式)。解决办法:使用Application
的上下文。
b:Handler
消息队列存在延时消息导致内存泄漏。解决办法:在onDestroy
方法中取消注册。
c: 各种注册的监听器忘记移除导致内存泄漏。解决办法:在onDestroy
方法中取消注册
内存泄漏排查工具
AS Monitor
MAT
LeakCanary
2. HashMap和Hashtable的区别
HashMap是map接口的子类,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而HashTable不允许。
HashMap是HashTable的轻量级实现(非线程安全的实现),它们都完成了Map接口,由于非线程安全,效率上可能高于HashTable。
HashMap把HashTable的contains方法去掉了,改成containsvalue和containsKey。
HashMap是Java1.2引进的Map interface的一个实现,HashTable继承自Dictionary类。
HashTable的方法是Synchronize的,而HashMap不是,在多个线程访问HashTable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供同步。但是如果使用Java 5或以上的话,可以用ConcurrentHashMap代替HashTable。
HashTable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差别。
3. ScrollView嵌套ListView的解决方案及其原理
自定义ListView解决: 重写其中的onMeasure()方法
原因: ScrollView默认把Childview设置为UNSPEFEIED模式,而该模式下的ListView给自己的测量的高度就是第一个item的高度。
原理:
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
这个方法的作用是根据大小和模式来生成一个int值,这个int值封装了模式和大小信息。
(未完...)
网友评论