Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。
这里重点介绍一下软引用和弱引用。
如 果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对 象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象 被垃圾回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
如 果一个对象只具有弱引用,那么在垃圾回收器线程扫描的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃 圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。弱引用也可以和一个引用队列(ReferenceQueue)联合使用, 如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
弱引用与软引用的根本区别在于:只具有弱引用的对象拥有更短暂的生命周期,可能随时被回收。而只具有软引用的对象只有当内存不够的时候才被回收,在内存足够的时候,通常不被回收。
在 java.lang.ref包中提供了几个类:SoftReference类、WeakReference类和PhantomReference类,它们 分别代表软引用、弱引用和虚引用。ReferenceQueue类表示引用队列,它可以和这三种引用类联合使用,以便跟踪Java虚拟机回收所引用的对象 的活动。
在Android应用的开发中,为了防止内存溢出,在处理一些占用内存大而且声明周期较长的对象时候,可以尽量应用软引用和弱引用技术。
下面以使用软引用为例来详细说明。弱引用的使用方式与软引用是类似的。
假 设我们的应用会用到大量的默认图片,比如应用中有默认的头像,默认游戏图标等等,这些图片很多地方会用到。如果每次都去读取图片,由于读取文件需要硬件操 作,速度较慢,会导致性能较低。所以我们考虑将图片缓存起来,需要的时候直接从内存中读取。但是,由于图片占用内存空间比较大,缓存很多图片需要很多的内 存,就可能比较容易发生OutOfMemory异常。这时,我们可以考虑使用软引用技术来避免这个问题发生。
首先定义一个HashMap,保存软引用对象。
private Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>(); |
再来定义一个方法,保存Bitmap的软引用到HashMap。
public void addBitmapToCache(String path) { // 强引用的Bitmap对象 Bitmap bitmap = BitmapFactory.decodeFile(path); // 软引用的Bitmap对象 SoftReference<Bitmap> softBitmap = new SoftReference<Bitmap>(bitmap); // 添加该对象到Map中使其缓存 imageCache.put(path, softBitmap); }
|
获取的时候,可以通过SoftReference的get()方法得到Bitmap对象。
public Bitmap getBitmapByPath(String path) { // 从缓存中取软引用的Bitmap对象 SoftReference<Bitmap> softBitmap = imageCache.get(path); // 判断是否存在软引用 if (softBitmap == null) { return null; } // 取出Bitmap对象,如果由于内存不足Bitmap被回收,将取得空 Bitmap bitmap = softBitmap.get(); return bitmap; } |
使用软引用以后,在OutOfMemory异常发生之前,这些缓存的图片资源的内存空间可以被释放掉的,从而避免内存达到上限,避免Crash发生。
需 要注意的是,在垃圾回收器对这个Java对象回收前,SoftReference类所提供的get方法会返回Java对象的强引用,一旦垃圾线程回收该 Java对象之后,get方法将返回null。所以在获取软引用对象的代码中,一定要判断是否为null,以免出现 NullPointerException异常导致应用崩溃。
经验分享:
到底什么时候使用软引用,什么时候使用弱引用呢?
个人认为,如果只是想避免OutOfMemory异常的发生,则可以使用软引用。如果对于应用的性能更在意,想尽快回收一些占用内存比较大的对象,则可以使用弱引用。
还有就是可以根据对象是否经常使用来判断。如果该对象可能会经常使用的,就尽量用软引用。如果该对象不被使用的可能性更大些,就可以用弱引用。
另外,和弱引用功能类似的是WeakHashMap。WeakHashMap对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收,回收以后,其条目从映射中有效地移除。WeakHashMap使用ReferenceQueue实现的这种机制。
优化系列相关博文:
相关推荐
总之,ListView作为Android开发中的重要组件,理解其工作原理和优化技巧对于提升用户体验至关重要。在实际项目中,开发者应灵活运用上述知识点,结合业务需求,实现高效、流畅的列表展示。通过不断的实践和学习,你...
在Android应用开发中,内存优化是一项至关重要的任务,它直接影响到应用的性能、稳定性和用户体验。本文将深入探讨Android系统中的常见内存泄露问题及其优化方案,主要针对Java编程语言。 一、内存泄露的理解与类型...
以下将详细介绍Android开发中常见的内存泄露场景及优化方案。 首先,内存泄露是指当一个对象不再被使用时,由于其他对象仍然持有对其的引用,导致该对象无法被垃圾回收器回收,从而长时间占用内存,最终可能导致...
10. **性能优化**: 当处理大量图片时,需要考虑内存优化,如使用LruCache、BitmapFactory.Options的inSampleSize属性来减小图片占用的内存,以及合理使用软引用和弱引用来防止内存泄漏。 了解并掌握以上知识点,将...
解决方案是避免使用静态变量持有Activity或Context,或者使用弱引用(WeakReference)或软引用(SoftReference)。 2. **单例模式**:单例模式在很多情况下很有用,但如果单例中持有Context的强引用,也会造成内存...
《Android源码——优化大师源代码》 在深入解析Android优化大师源代码之前,我们首先需要理解Android系统的基本架构和工作原理。...对于想要深入Android开发或者想要创建类似工具的开发者来说,这是一个宝贵的资源。
- **内存管理**:合理使用软引用和弱引用,防止内存泄漏。 8. **国际化与本地化** - **res/values** 目录下的不同语言文件,支持多语言环境。 9. **测试** - **单元测试**:对应用的各个组件进行独立测试。 - ...
在Android应用开发中,RecyclerView和CardView是两个非常重要的组件,它们被广泛用于构建高效、动态且美观的用户界面。这篇“Android Training学习笔记”主要围绕这两个组件展开,旨在帮助开发者提升他们的Android...
"android安卓图片的三级缓存DEMO 三层缓存示例下载 强引用 软引用"这个资源提供了对图片加载优化的一个常见实践——三级缓存机制的实现。下面将详细讲解这一知识点。 首先,我们来理解什么是图片的三级缓存。在...
本资料包“安卓Android源码——精典源码之引用第三方库的方法”旨在深入探讨如何在Android项目中集成和使用外部库。下面将详细阐述这一主题。 1. **依赖管理工具Gradle** Android项目主要使用Gradle作为构建工具...
综合来看,这个“Android课程设计——简易闹钟”项目涵盖了Android开发中的基础元素,包括数据库交互、定时任务处理、后台服务的运用,以及对构建工具和版本管理的理解。通过实践这样的项目,学生能够深入理解...
3. **Activity生命周期**:理解Activity在不同状态之间的转换是Android开发的关键。源码揭示了如何处理onCreate、onStart、onResume、onPause、onStop和onDestroy等方法,以及如何进行状态保存和恢复。 4. **Intent...
综上所述,开发Android版2048游戏涉及Android Studio的使用、界面布局设计、事件处理、数据管理等多个方面,是提升Android开发技能的绝佳实践项目。而`main.zip`文件可能包含了项目的源代码和资源文件,供开发者学习...
在Android开发中,源码是程序的核心部分,它包含了一系列的Java类文件和其他资源文件,开发者可以通过查看和修改源码来理解游戏的工作原理、实现功能以及优化性能。 【描述】"安卓Android源码——节奏大师.rar"提示...
【Android开发的贪吃蛇——课程设计详解】 贪吃蛇是一款经典的电子游戏,深受各年龄段玩家的喜爱。在Android平台上开发这款游戏,不仅可以帮助开发者巩固基础知识,还能提升对Android应用开发的理解和实践能力。本...
在Android中,弱引用和软引用可以用来帮助管理对象生命周期,它们不会阻止垃圾回收,即使有引用存在,当内存紧张时,这些对象也会被回收。 2. **大对象与内存碎片**:大对象(如位图)直接进入老年代,可能导致频繁...
这提示我们将接触到Android SDK、Android Studio开发环境、AndroidManifest.xml文件、Activity管理、Intent通信机制、服务、广播接收器等Android特有的开发概念和技术。 【文件名称列表解析】 虽然这里列出的是...
在Android开发领域,页面特效是提升用户体验和应用吸引力的关键元素之一。这个名为“Android项目之——页面特效集合(附源码).7z”的压缩包文件显然包含了多种Android页面特效的示例代码,旨在帮助开发者学习和实现...
在Android开发领域,优化技术是提升用户体验、节省资源和提高应用性能的关键环节。"Android优化技术详解"这一主题涵盖了多个方面,旨在帮助开发者构建高效、流畅的应用程序。下面,我们将深入探讨这些关键技术点。 ...
在Android应用程序开发中,智能指针是用于管理内存的重要工具,尤其是在C++ Native层的编程中。本系列文章源代码主要探讨了如何在...对于Android开发人员来说,掌握智能指针的使用是提高代码质量和效率的关键一步。