检测内存情况
检查你应该使用多少内存:
public void doSomethingMemoryIntensive() {
// Before doing something that requires a lot of memory,
// check to see whether the device is in a low memory state.
ActivityManager.MemoryInfo memoryInfo = getAvailableMemory();
if (!memoryInfo.lowMemory) {
// Do memory intensive work ...
}
}
// Get a MemoryInfo object for the device's current memory status.
private ActivityManager.MemoryInfo getAvailableMemory() {
ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
return memoryInfo;
}
实现ComponentCallbacks2接口响应事件进行内存释放
import android.content.ComponentCallbacks2;
// Other import statements ...
public class MainActivity extends AppCompatActivity
implements ComponentCallbacks2 {
// Other activity code ...
/**
* Release memory when the UI becomes hidden or when system resources become low.
* @param level the memory-related event that was raised.
*/
public void onTrimMemory(int level) {
// Determine which lifecycle or system event was raised.
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
/*
Release any UI objects that currently hold memory.
The user interface has moved to the background.
*/
break;
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
/*
Release any memory that your app doesn't need to run.
The device is running low on memory while the app is running.
The event raised indicates the severity of the memory-related event.
If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will
begin killing background processes.
*/
break;
case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
/*
Release as much memory as the process can.
The app is on the LRU list and the system is running low on memory.
The event raised indicates where the app sits within the LRU list.
If the event is TRIM_MEMORY_COMPLETE, the process will be one of
the first to be terminated.
*/
break;
default:
/*
Release any non-critical data structures.
The app received an unrecognized memory level value
from the system. Treat this as a generic low-memory message.
*/
break;
}
}
}
应用切换
当用户在应用程序之间切换时,Android会保留不是前台的应用程序 - 即用户不可见或在最近最少使<br/>
(LRU)缓存中运行音乐播放等前台服务。例如,当用户首次启动应用程序时,会为其创建一个进程;但是<br/>
当用户离开应用程序时,该进程不会退出。系统会保持进程缓存。如果用户稍后返回应用程序,系统将重<br/>
新使用该过程,从而使应用程序切换更快。 如果您的应用程序具有缓存进程并且它保留了当前不需要的<br/>
内存,那么即使用户未使用它,您的应用程序也会影响系统的整体性能。由于系统内存不足,因此从最近<br/>
最少使用的进程开始,它会终止LRU缓存中的进程。系统还会考虑保留最多内存的进程,并可以终止它们以<br/>
释放RAM。
谨慎使用服务
- 当服务不需要运行时,你应该及时关闭它
- 使用JobScheduler 替代服务
- 使用IntentService
高效的内存容器
- [Java 常用数据结构](https://mp.weixin.qq.com/s/5BO92rFoSh4sd1ZlgDk5zw)
- [Autoboxing]自动装箱
- 常量替代枚举类型 (13倍左右)
- Android优化过容器SparseArray Family、ArrayMaps(数据量 < 1000)
减少不必要的代码抽象以减轻代码量及方法数
数据序列化:
Protocol buffers > Parcelable(AS Plugin Parcelable) > Serializable
使用Dagger2 注解框架
使用反射的其他依赖注入框架倾向于通过扫描代码注释来初始化进程。此过程可能需要更多的CPU周期和RAM,并且可能会在应用程序启动时导致明显的延迟.
谨慎使用外部库、多数外部库不是针对移动端编写的、需要进行优化后使用
注意内存泄露、
尤其是Static对象、持有View、Context对象的异步回调、使用ApplicationContext
删除不必要的资源、第三方库减小内存消耗
使用多进程
使用Java引用,而使用C++内存分配来分配的内存,当Java引用不可达时,这不部分内存可能引起泄露<br/>
可以使用Java PhantomReference引用
[推荐阅读]
网友评论