`
苗振忠
  • 浏览: 56714 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

内存的优化

 
阅读更多

1.内存的优化

1.1 临界状态的处理

Ø临界状态:

当缓存内容过多,同时系统,内存又相对较低时的状态;

Ø临界状态处理:

1. 低内存预警:

每当进行数据缓存时需要判断当前系统的内存值是否低于应用预设的最低内存

如果是,提示用户应用将在低内存环境下运行

Tips

Intent.ACTION_DEVICE_STORAGE_LOW;

设备内存不足时发出的广播,此广播只能由系统使用,其它APP不可用;

Intent.ACTION_DEVICE_STORAGE_OK;

设备内存从不足到充足时发出的广播,此广播只能由系统使用,其它APP不可用;

2.构建高速缓存(扩展)

1.2对象的引用的级别

JDK 1.2以前的版本中,若一个对象不被任何变量引用,那么程序就无法再使用这个对象。即只有对象处于可触及(reachable)状态,程序才能使用它。

JDK 1.2版本开始,把对象的引用分为4种级别,从而使程序能更加灵活地控制对象的生命周期。

4种级别由高到低依次为:强引用、软引用、弱引用和虚引用

1.2.1强引用(StrongReference

如:Object object = new Object();

特点:

a.强引用是使用最普遍的引用

b.如果一个对象具有强引用,那垃圾回收器绝不会回收它,内存不足时,宁抛异常OOM,程序终止也不回收;

1.2.2软引用(SoftReference

JDK提供创建软引用的类SoftReference

通过“袋子”(sr)来拿“内容”(object)

系统发现不足时,会将“袋子”中的“内容”回收,这时,将拿到null了,此时,这个“壳”也没有用了,需要干掉;

Object object = newObject();//占用系统内容较多的对象(内容)

SoftReference sr = newSoftReference(object);//object对象的引用级别降低(袋子)

SoftReference的特点是它的实例保存对一个Java对象的引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。

一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。

另外,一旦垃圾线程回收该Java对象之后,get()方法将返回null

特点:

a.如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;

b.如果内存空间不足了,就会回收这些对象的内存,会在抛出OOM之前回收掉;

c. 只要垃圾回收器没有回收它,该对象就可以被程序使用软引用可用来实现内存敏感的高速缓存

d. 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,

Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

Ø说明一下软引用:

Object object = newObject();//占用系统内容较多的对象(内容)

SoftReference sr = newSoftReference(object);//object对象的引用级别降低(袋子)

此时,对于这个Object对象,有两个引用路径:

a.一个是来自SoftReference对象的软引用;

b.一个来自变量object的强引用,所以这个Object对象是强可及对象;

随即,我们可以结束object对这个Object实例的强引用:

object = null;

此后,这个Object对象成为了软可及对象;

如果垃圾收集线程进行内存垃圾收集,并不会因为有一个SoftReference对该对象的引用而始终保留该对象;

Java虚拟机的垃圾收集线程对软可及对象和其他一般Java对象进行了区别对待:

软可及对象的清理是由垃圾收集线程根据其特定算法按照内存需求决定的。

也就是说,垃圾收集线程会在虚拟机抛出OutOfMemoryError之前回收软可及对象,而且虚拟机会尽可能优先回收长时间闲置不用的软可及对象,

对那些刚刚构建的或刚刚使用过的“新”软可反对象会被虚拟机尽可能保留。

在回收这些对象之前,我们可以通过,Object anotherRef=(Object)aSoftRef.get(),重新获得对该实例的强引用。

回收之后,调用get()方法就只能得到null了。

1.2.3弱引用(WeakReference

弱引用与软引用的区别:只具有弱引用的对象拥有更短暂的生命周期。

特点:

a.生命周期比软引用更短;

b.在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

c.不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象

d.类似于软引用,弱引用也可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,

Java虚拟机就会把这个弱引用加入到与之关联的引用队列中

1.2.4虚引用(PhantomReference

虚引用顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

特点:

a.形同虚设;

b.可用来跟踪对象被垃圾回收器回收的活动;

c.虚引用与软引用和弱引用的一个区别在于:

虚引用必须和引用队列 ReferenceQueue)联合使用,

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中;

1.3ReferenceQueue与软引用结合使用

ØReferenceQueue的作用:

引用队列,在检测到适当的可到达性更改后,垃圾回收器将已注册的引用对象添加到该队列中

利用ReferenceQueue的特性,即用来清除失去了软引用对象的SoftReference

Ø为什么需要ReferenceQueue

作为一个Java对象,SoftReference对象除了具有保存软引用的特殊性之外,也具有Java对象的一般性。

所以,当软可及对象(SoftReference袋中对象)被回收之后,虽然这个SoftReference对象的get()方法返回null

但这个SoftReference对象已经不再具有存在的价值,需要一个适当的清除机制,避免大量SoftReference对象带来的内存泄漏。

这时候需要用到ReferenceQueue类;

如果在创建SoftReference对象的时候,使用了一个ReferenceQueue对象作为参数提供给SoftReference的构造方法,如:

Object object = newObject();//占用系统内容较多的对象(内容)

ReferenceQueue queue = newReferenceQueue();//SoftReference的队列

SoftReference sr=newSoftReference(object, queue);

那么当这个SoftReference所软引用的object被垃圾收集器回收的同时,sr所强引用的SoftReference对象被列入ReferenceQueue

也就是说,ReferenceQueue中保存的对象是Reference对象,而且是已经失去了它所软引用的对象的Reference对象。

另外从ReferenceQueue这个名字也可以看出,它是一个队列;

当我们调用它的poll()方法的时候,如果这个队列中不是空队列,那么将返回队列前面的那个Reference对象。

在任何时候,我们都可以调用ReferenceQueuepoll()方法来检查是否有它所关心的非强可及对象被回收。

如果队列为空,将返回一个null,否则该方法返回队列中前面的一个Reference对象。

利用这个方法,我们可以检查哪个SoftReference所软引用的对象已经被回收。

于是我们可以把这些失去所软引用的对象的SoftReference对象清除掉。

1.4 软引用的示例(彩票)

构建高速缓存

Ø在手机彩票中的UIManager类中:

UIManager如果管理了100个界面,每加一个界面,大概100KB左右,100个,那就多了;

这就涉及到内存优化:

a.应用如何在低内存的情况下运行;

b.UIManagerMap进行处理;

c.判断手机当前的可用内存(10M100个界面左右)与 应用需要的最大内存(峰值))来创建UIManager的缓存Map对象;

但是在java中目前并没有提供SoftHashMap,在Map接口的实现类里可以发现WeakHashMap这是针对弱引用提供的实现类,

但是弱引用不能满足我们当前的需求,我们需要一个能够通用的管理明感数据的集合,我们需要自己处理SoftHashMap

Ø软引用SoftHashMap实现步骤:

基本功能

自定义HashMap<K,V>的子类,其实HashMap只是想当于一个“壳”,里面常用的方法(需求中用到的方法)一一复写;

创建一个临时的HashMap<K, SoftReference<V>>,关于常用的方法中均需操作该map信息;

处理putgetcontainsKey方法;

优化处理

GC回收软引用实例之后,需要利用GC帮助我们完成回收掉的软引用集合的填充

轮训该回收掉的软引用集合,处理“空袋子”

Ø软引用SoftHashMap的代码(最终版)

/**

* 构建高速缓存的map

* 软引用的map,将需要用到的方法(根据需求),如:getputcontainsKey等重写

* @param<K>

* @param<V>

*/

publicclassSoftHashMap<K, V>extendsHashMap<K, V> {

// 降低对象的引入的级别的步骤:

// 1.V的应用级别降低

// 2.回收“袋子”

privateHashMap<K, MySoftReference<K, V>>softMap;

privateReferenceQueue<V>queue;//V的袋子的队列

publicSoftHashMap() {

softMap= newHashMap<K, MySoftReference<K, V>>();

queue=newReferenceQueue<V>();

}

/**重写放入数据方法*/

@Override

publicV put(K key, V value) {

// 占用内存较多的对象包了一层袋子,GC时,会往queue中加“MySoftReference”的引用

MySoftReference<K, V> srValue = newMySoftReference<K, V>(key, value,queue);

softMap.put(key, srValue);

returnnull;

}

/** 重写获取方法*/

@Override

publicV get(Object key) {

this.clearNullSR();//先清理空袋子

MySoftReference<K, V> sr = softMap.get(key);

if(sr !=null) {

returnsr.get();//此引用所引用的对象,即袋子中的内容

}

returnnull;

}

/**重写containsKey方法*/

@Override

publicbooleancontainsKey(Object key) {

this.clearNullSR();

returnsoftMap.containsKey(key);

}

/**回收“空袋子”*/

@SuppressWarnings("all")

privatevoidclearNullSR() {

// 方案1:遍历softMap中的所有元素,如发现V=null,在softMap中删除对应的空袋子子

// 方法2:让GC记录回收的内容(集合中:存储空袋子的引用),如果GC回收内容了,集合的size>0

MySoftReference<K, V> poll = (MySoftReference<K, V>)queue.poll();

while(poll !=null) {

softMap.remove(poll.key);

poll = (MySoftReference<K, V>) queue.poll();

}

}

/** 加强版的袋子(包装设计模式的应用):存储一下key*/

@SuppressWarnings("hiding")

privateclassMySoftReference<K, V> extendsSoftReference<V> {

privateObjectkey;//为袋子添加一个标签,即为 map 中的 key

publicMySoftReference(K key, V r, ReferenceQueue<?superV> q) {

super(r, q);

this.key= key;

}

}

}

ØUIManager中的代码片段:

/********* 需要内容优化100个界面,内存不足是,释放掉map里面存放的一些对象

* 1.降低对象引用级别;

* 2.返回键的处理(如果上一个界面被回收掉了,直接返回到首页(同时提示用户应用在低内存下运行))

* *****************/

/** 缓存BaseView的子类Mapkey为类的简单名称*/

privatestaticMap<String, BaseView>baseViewMap=newHashMap<String, BaseView>();

static{

if(MemoryManager.hasAcailMemory()) {

baseViewMap=newHashMap<String, BaseView>();

} else{

// 模拟内存不足的情况下:

baseViewMap=newSoftHashMap<String, BaseView>();//构建软引用的HashMap对象

}

}

返回键的处理:

/**

* 处理返回键操作

* @returnfalse表示模拟的Activity“栈”中没有view对象了,

* true 表示移除当前view

*/

publicbooleangoBack() {

String key = "";//栈顶

if(historyStack.size() > 0) {

key = historyStack.getFirst();

}

if(StringUtils.isNotBlank(key)) {

BaseView targetView = baseViewMap.get(key);//依据key获取到对应BaseView的子类对象

if(targetView !=null) {

if(targetView.getClass() ==currentView.getClass()) {//比对栈顶元素和正在显示的是否相同

if(historyStack.size() == 1) {//判断历史集合中是否还有,(如果size==1),返回false(栈中保留一个view

returnfalse;

}

historyStack.removeFirst();//如果相同做删除的操作

returngoBack();//之后再次获取栈顶元素

} else{

if(currentView!=null) {

currentView.onPause();//移除界面后,清理工作

}

middle.removeAllViews();//如果不同:界面的切换

middle.addView(targetView.getView());

targetView.onResume();//进入到界面后调用

currentView= targetView;//更新当前正在显示的界面

changeTitleAndBottom();//切换底部和标题容器

returntrue;

}

} else{// 都被回收掉了

// 提示用户--

PromptManager.showToast(getContext(),"应用在低内存的环境下运行");

// 清理返回键

clear();

// 回到首页

this.changeView(Hall.class,null);

}

}

returnfalse;

}

1.5软硬合并(自学)

Android 3.1以后版本中提供android.util.LruCache<K,V>来实现硬引用;

Ø硬引用:

指定内存大小,一旦满了,会丢弃一部分内容至软引用的集合中,可以被系统GC了,而不是不是彻底干掉了

2.软引用SoftHashMap的代码(初版)

/**

* 软引用的map,将需要用到的方法(根据需求),如:getputcontainsKey等重写

* @param<K>

* @param<V>

*/

publicclassSoftHashMap1<K, V>extendsHashMap<K, V> {

// 降低对象的引入的级别的步骤:

// 1.V的应用级别降低

//2.回收“壳”

privateHashMap<K, SoftReference<V>>softMap;

publicSoftHashMap1() {

softMap= newHashMap<K, SoftReference<V>>();

}

@Override

publicV put(K key, V value) {

SoftReference<V> srValue = newSoftReference<V>(value);//占用内存较多的对象包了一层壳

softMap.put(key, srValue);// key绑定在一起

returnnull;

}

@Override

publicV get(Object key) {

SoftReference<V> sr = softMap.get(key);

returnsr.get();//此引用所引用的对象,即壳中的内容

}

@Override

publicbooleancontainsKey(Object key) {

// softMap.containsKey(key); // 如果V(内容)被GC回收了,这里就是个空壳(里面没有内容了),这个判断没有意义

V v = get(key);

booleanisContain =false;

if(v !=null) {

isContain = true;

}

returnisContain;

}

/**

* 回收“空壳子”

*/

privatevoidclearNullSR(){

// 方案1:循环softMap中的所有元素,如发现V=null,在softMap中删除对应的空壳子

// 方法2:不循环,让GC记录回收的内容(集合中:存储空壳子的引用),如果GC回收内容了,集合的size>0

}

}

分享到:
评论

相关推荐

    内存优化工具大比拼 内存优化工具大比拼

    内存优化工具是提升计算机性能的重要辅助软件,它们可以帮助管理计算机的RAM(随机存取存储器),使其更加高效地工作。本文将对比分析三款内存优化工具:RAMIdlePro、香蕉内存整理以及Windows优化大师内存整理。 ...

    内存优化工具.内存优化让你电脑持久有力!

    内存优化是计算机性能提升的重要手段,尤其是在运行大型应用程序或游戏时,有效的内存管理能显著改善系统响应速度和稳定性。本文将深入探讨内存优化工具的工作原理、优化方法以及如何使用这类工具来解决电脑运行缓慢...

    易语言之内存优化模块

    易语言之内存优化模块是专为易语言编程环境设计的一种扩展功能,旨在提高程序运行时的内存管理效率和性能。这个模块通过优化内存分配和回收策略,帮助开发者编写出更节省资源、运行更快的易语言程序。在易语言中,...

    windows内存优化软件

    在IT领域,尤其是在服务器管理中,内存优化是一个关键的环节,因为它直接影响到系统的性能和响应速度。"Windows内存优化软件"就是专为了解决这个问题而设计的工具,它能够帮助用户更有效地管理和利用服务器的内存...

    易语言物理内存优化

    本篇将深入探讨"易语言物理内存优化"这一主题,包括其核心概念、相关API函数以及如何在易语言中实现内存优化。 物理内存,也被称为RAM(Random Access Memory),是计算机存储数据的主要临时场所。程序运行时,大...

    最新版内存优化精灵下载.zip

    内存优化精灵是一款针对计算机内存管理的工具,旨在帮助用户提高电脑运行效率,减少因内存占用过高而导致的系统卡顿现象。这款软件通过智能分析和优化内存分配,释放被占用但不再使用的内存资源,从而提升系统性能。...

    cpu内存优化器

    "CPU内存优化器"是一种工具,旨在通过智能管理和调整CPU及内存资源,提升电脑性能,尤其适用于游戏工作室等需要高性能、稳定运行环境的场景。 CPU(中央处理器)是计算机的大脑,执行所有计算和逻辑操作。优化CPU...

    易语言模块内存优化.rar

    本压缩包“易语言模块内存优化.rar”显然关注的是如何在易语言编程环境中提高程序的内存管理效率,从而优化程序性能。下面将详细讨论易语言中的内存管理和优化策略。 1. **内存分配与释放** 在易语言中,内存管理...

    smartram电脑运行内存优化的小工具

    【smartram电脑运行内存优化小工具详解】 内存优化是提升电脑性能的重要手段,尤其是在现代计算机系统中,程序运行过程中可能会占用大量内存,导致系统运行缓慢。"smartram"便是一款专注于内存优化的小工具,它以其...

    内存优化整理工具 绿色版

    "内存优化整理工具 绿色版"是一个专为此目的设计的实用工具,它可以帮助用户有效地整理和优化计算机的内存资源,提高系统的运行效率和响应速度。 内存整理是指通过特定的技术手段,重新组织内存中的数据分布,以...

    android listview内存优化

    本文将深入探讨如何对ListView进行内存优化,确保10M级别的图片加载时,应用依然能保持流畅运行,避免内存溢出和线程阻塞。 首先,理解内存溢出(OOM,Out of Memory)的原因至关重要。当应用程序请求的内存超过...

    内存优化

    内存优化

    Eclipse的内存优化与内存不足问题.pdf

    ### Eclipse的内存优化与内存不足问题 #### 一、引言 在开发过程中,经常会遇到IDE(集成开发环境)如Eclipse运行缓慢甚至崩溃的情况,这往往与内存管理不当有关。本文将详细介绍如何针对Eclipse进行内存优化,解决...

    内存优化专家_V7.1注册版

    内存优化专家_V7.1注册版是一款专门针对计算机内存管理的软件工具,旨在提升系统性能,防止因内存泄漏或过度占用导致的系统卡顿。它通过智能化地清理、整理和优化内存,帮助用户改善计算机运行速度,提高工作效率。 ...

    Android学习资料之内存优化.zip

    在Android开发中,内存优化是提升应用性能和用户体验的关键因素之一。这个名为"Android学习资料之内存优化.zip"的压缩包包含了一些关于Android内存优化的重要文档,这些文档深入探讨了常见的内存泄露问题以及对应的...

    Tomcat JVM内存优化(Linux环境)

    ### Tomcat JVM内存优化(Linux环境) 在Linux环境下运行Tomcat服务器时,经常会遇到与Java虚拟机(JVM)相关的内存溢出问题。这些问题通常表现为`java.lang.OutOfMemoryError`异常,具体又分为两类:`PermGen ...

    CPU内存优化源码

    易语言 内存优化源码 不解释 CPU内存优化源码

    内存优化模块.ec内存优化模块.ec

    内存优化模块.ec内存优化模块.ec内存优化模块.ec内存优化模块.ec内存优化模块.ec内存优化模块.ec

    只有306k的纯绿色中文内存优化压缩整理软件.rar

    标题中的“只有306k的纯绿色中文内存优化压缩整理软件.rar”表明这是一款小巧、轻量级的内存优化工具,其体积仅为306KB,非常适合在资源有限的设备上使用。"纯绿色"通常意味着这款软件无需安装,解压即用,不写入...

    内存优化工具

    内存优化工具是针对计算机系统运行效率提升的一种实用软件,尤其对于32位和64位系统用户来说,它能够有效地管理并优化内存资源,解决电脑运行卡顿的问题。内存(RAM)是计算机运行过程中临时存储数据的重要部分,当...

Global site tag (gtag.js) - Google Analytics