java的一个非常重要的优点是垃圾的回收,不再使用的对象内存会被垃圾回收器释放,当然还是有可能出现内存泄漏, 垃圾回收器会帮你管理内存,它做的不仅仅是释放不用的内存。 只有当某个对象不再被引用的时候,它的内存才会被回收,当被释放的对象引用扔然需要的时候就回出现内存泄漏, 比如在横竖屏切换时当前的activity会被销毁,数据将会全部丢失。解决的方法也很简单, 在清单文件的activity中添加 android:configChanges="orientation|keyboardHidden"或者复写 onConfigurationChanged()用于实现不同屏幕状态下的处理方式。 Android2.3中定义了strictMode类,它对检查内存泄漏有很大的帮助。在3.0以后的版本可以检查出: Activity泄漏,其他对象泄漏,对象没有关闭造成的泄漏。 当然在应用中使用StrictMode类不仅仅用来检查内存泄漏,磁盘的读写耗时,网络操作的耗时,自定义速度的耗时 **此功能仅仅在开发和测试时开启,应用发布时要禁用。**
// 磁盘的读写速度 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() // .detectAll() .penaltyLog() .build()); // SQLite 检测 StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); // 检测那些代码执行的缓慢 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectCustomSlowCalls() // noteSlowCall() 有可能造成的缓慢代码 .penaltyDeath() .build()); // 检测网络交互耗时 StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectNetwork() .penaltyDeath() .build());
在这个特殊的实例中,StrictMode检测到一个违反,仅仅记录下这个问题信息。 垃圾回收可能会在不定的时间触发,你基本上没有办法来控制它出现的时机,有时你可以通过system.gc() 来提醒一下Android,但最终的回收时间还是要看虚拟机的心情。 以下情况会触发垃圾回收: GC_FOR_MALLOC: 当堆被占满不能进行内存分配时,在分配新的对象前,部分没有被引用的对象会被回收掉。 GC_CONCURRENT: 当部分垃圾可供回收时,通常有很多对象可以回收。 GC_EXPLICIT: 显示调用System.gc()产生的垃圾回收。 GC_EXTERNAL_ALLOE: Android 3.0 Honeycomb 及以上版本不会出现(一切都在堆中被分配)。 GC_HPROF_DUMP_HEAP: 发生在创建HPROF文件时(HPROF实际上是JVM中的一个native的库)。 垃圾回收要花费时间,减少分配/释放对象的数量可以提高性能。在Android 2.2 之前垃圾回收在主线程中执行的, 所以严重的了降低了应用的速度和效率。在Android 2.3以后将垃圾回收移到了一个单独的线程中,但是在垃圾回收时还是会对主线程造成一定的影响。 Android 中定义了几个API,我们可以用他们来了解内存的使用所占的资源。 ActivityManager 的 getMemoryInfo() 系统可用内存信息。 ActivityManager 的 getMemoryClass() 获取堆内存的信息。 ActivityManager 的 getLargeMemoryClass() 获取最大的堆内存。 Debug 的 dumpHprofData() 将进程的内存写入到指定地址中。 Debug 的 getMemoryInfo() 检索各种统计有关该进程的内存映射。
ActivityManager manager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); // 这里使用 memoryInfo 带来的数据 manager.getMemoryInfo(memoryInfo); Debug.MemoryInfo debugMemory = new Debug.MemoryInfo(); // 这里使用 debugMemory的数据 Debug.getMemoryInfo(debugMemory);
你的应用不能独占平台,他要与许多其他的应用共享资源。因此当内存不足以分配给所有程序时,Android会要求应用及应用的组件节省资源。 如使用Fragment 中的replace在每一次切换的时候将上一个Fragment收回。 使用ComponentCallbacks接口定义 onLowMemory(),它对所有的应用组件都是相同的。 当他被调用时,组件基本会被要求释放那些并不会被用到的内存。 通常情况下onLowMemory()将释放: 缓存或缓存的条目 可以再次按照需求生成位图对象 不可见的布局对象 数据库对象 删除对象的时候要注意,因为重新创建是要消耗内存的,如果没有释放足够的内存可能会导致应用程序的进程被干掉。 在代码中推迟初始化是一个好习惯,它可以让你在实现onLowMemory()时几乎不用改动其他地方的代码。