OOM&内存优化

OOM&内存优化
OOM&内存优化

OOM讲课内容

OOM现象:

05:15:04.764: ERROR/dalvikvm-heap(264): 3528000-byte external allocation too large for …

05:15:04.764: ERROR/(264): VM won’t let us allocate 3528000 bytes

05:15:04.764: DEBUG/skia(264): — decoder->decode returned false

05:15:04.774: DEBUG/AndroidRuntime(264): Shutting down VM

这几句的意思是,我们的程序申请需要3528000byte太大了,虚拟机不同意给我们,虚拟机shut down 自杀了。这个现象,比较常见在需要用到很多图片或者要用很大图片的APP开发中。

OOM(Out Of Memory)错误,什么是OOM?

通俗讲就是当我们的APP需要申请一块内存用来装图片的时候,系统觉得我们的APP所使用的内存已经够多了,不同意给我们的APP更多的内存,即使手机系统里还有1G空余的内存,然后系统抛出OOM,程序弹框shut down。

为什么有OOM,OOM的必然性!

因为android系统app的每个进程或者每个虚拟机有个最大内存限制,如果申请的内存资源超过了这个限制,系统就会抛出OOM错误。跟整个设备的剩余内存没太大关系。比如比较早的android 系统一个虚拟机最多16M内存,当一个app启动后,虚拟机不停的申请内存资源用来装载图片,当超过内存上限时就OOM。

Android系统APP内存限制怎么确定的?

Android的APP内存组成:

APP内存由dalvik内存和native内存2部分组成,dalvik也就是java堆,创建的对象就是在这里分配的,而native是通过c/c++ 方式申请的内存,Bitmap就是以这种方式分配的(android3.0 以后,系统都默认是通过dalvik分配的,native作为堆来管理)。这2部分加起来不能超过android 对单个进程、虚拟机的内存限制。

每个手机的内存限制大小是多少?

ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); activityManager.getMemoryClass();

以上方法会返回以M为单位的数字,不同的系统平台或设备上的值都不太一样,比如:HTC G7默认24M,Galaxy 36M,emulator-2.3 24M,等等。我的moto xt681 是42M。3.0系统的设备默认是48M。

上面取到是虚拟机的最大内存资源。而对于heap堆的大小限制,可以查看/system/build.prop文件。

dalvik.vm.heapstartsize=5m

dalvik.vm.heapgrowthlimit=48m

dalvik.vm.heapsize=256m

heapsize参数表示单个进程heap可用的最大内存,但如果存在如下参数:

dalvik.vm.heapgrowthlimit=48m表示单个进程heap内存被限定在48m,即程序运行过程中实际只能使用48m内存。

为什么android系统设定APP的内存限制?

1,要使开发者内存使用更为合理。限制每个应用的可用内存上限,可以防止某些应用程序恶意或者无意使用过多的内存,而导致其他应用无法正常运行。Android是有多进程的,如果一个进程(也就是一个应用)耗费过多的内存,其他的应用无法运行了。因为有了限制,使得开发者必须好好利用有限的资源,优化资源的使用。

2,即使有万千图片、千万数据需要使用到,但是特定时刻需要展示给用户看的总是有限,因为设备的屏幕显示就那么大,上面可以放的信息就是很有限的。大部分信息都是出于准备显示状态,所以没必要给予太多heap内存。也就是出现OOM现象,绝大部分原因是我们的程序设计上有问题,需要优化。比如可以通过时间换空间,不停的加载要用的图片,不停的回收不用的图片,把大图片解析到适合手机屏幕大小的图片等。

3,android上的APP使用独立虚拟机,每开一个应用就会打开至少一个独立的虚拟机。这样可以避免虚拟机崩溃导致整个系统崩溃,同时代价就是需要浪费更多内存。这些设计确保了android的稳定性。

不是android有gc会自动回收资源么,为什么还会OOM?

Android不是用gc会自动回收资源么,为什么app的哪些不用的资源不回收呢?

Android的gc会按照特定的算法回收程序不用的内存资源,避免app的内存申请越积越多。但是Gc一般回收的资源是哪些无主的对象内存或者软引用的资源,或者更软的引用资源,比如:Bitmap bt= BitmapFactory.decodeResource(this.getResources(), R.drawable.splash);

使用bt…//此时的图片资源是强应用,是有主的资源。

bt=null;

此时这个图片资源就是无主的了,gc心情好的时候就会去回收它。

Bitmap bt= BitmapFactory.decodeResource(this.getResources(), R.drawable.splash);

SoftReference< Bitmap > SoftRef=new SoftReference< Bitmap >(bt);

bt=null;

其他代码….。当程序申请很多内存资源时,gc有可能会释放SoftRef引用的这个图片内存。

bt=SoftRef.get(); 此时可能得到的是null;需要从新加载图片。当然这也说明了用软引用图片资源的好处,就是gc会自动根据需要释放资源,一定程度上避免OOM。

TIPS:编程要养成的习惯,不用的对象置null。其实更好是,不用的图片直接recycle。因为通过置null,让gc来回收,有时候还是会来不及。

For Android specific we should use the 'recycle' method rather than 'gc', because 'recycle' will free the memory at the same time, but calling 'gc' doesn't guaranty to run and free the memory for same time(if it is not too critical, we should not call gc in our code) and results can very every time.

One more thing using 'recycle' is faster than the 'gc' and it improves the performance.

怎么查看APP内存分配情况?

1,通过DDMS中的Heap选项卡监视内存情况:

Heap视图中部有一个叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。

在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量。

如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大,

直到到达一个上限后导致进程被kill掉。

2,在APP里可以通过Runtime类的totalMemory() ,freeMemory() 两个方法获取VM的一些内存信息,如:

Runtime.getRuntime().freeMemory();

Runtime.getRuntime().totalMemory ();

3,adb shell dumpsys meminfo com.android.demo

避免OOM的几个注意点:

1,适当调整图像大小,因为手机屏幕尺寸有限,分配给图像的显示区域有限,尤其对于超大图片,加载自网络或者sd卡,图片文件体积达到几M或者十几M的:

加载到内存前,先算出该bitmap的大小,然后通过适当调节采样率使得加载的图片刚好、或稍大即可在手机屏幕上显示就满意了:

BitmapFactory.Options opts = new BitmapFactory.Options();

opts.inJustDecodeBounds = true;

BitmapFactory.decodeFile(imageFile, opts); //此时不加载实际图片,只获取到图片的宽高,大致可以通过宽度*高度*4来估算图片大小。

opts.inSampleSize = computeSampleSize(opts, minSideLength, maxNumOfPixels); // Android提供了一种动态计算的方法computeSampleSize

opts.inJustDecodeBounds = false;

try {

return BitmapFactory.decodeFile(imageFile, opts);

} catch (OutOfMemoryError err) {

}

2,在ListView或Gallery等控件中一次性加载大量图片时,只加载屏幕显示的资源,尚未显示的不加载,移出屏幕的资源及时释放,可以采用强引用+软引用2级缓存方式,提高加载性能。

3,缓存图像到内存,采用软引用缓存到内存,而不是在每次使用的时候都从新加载到内存;

4,采用低内存占用量的编码方式,比如Bitmap.Config.ARGB_4444比Bitmap.Config.ARGB_8888

更省内存;

5,及时回收图像,如果引用了大量Bitmap对象,而应用又不需要同时显示所有图片,可以将暂时用不到的Bitmap对象及时回收掉。对于一些明确知道图片使用情况的场景可以主动recycle。比如:App的启动splash画面上的图片资源,使用完就recycle;对于帧动画,可以加载一张,画一张,

释放一张。

6,不要在循环中创建过多的本地变量;慎用static,用static来修饰成员变量时,该变量就属于该类,而不是该类的实例,它的生命周期是很长的。如果用它来引用一些资源耗费过多的实例,这时就要谨慎对待了。

public class ClassName {

private static Context mContext;

//省略

}

如果将Activity赋值到mContext的话。即使该Activity已经onDestroy,由于仍有对象保存它的引用,因此该Activity依然不会被释放。

7,自定义堆内存分配大小,优化Dalvik虚拟机的堆内存分配;

App避免OOM的几种方式

1,直接null或recycle。

对于app里使用的大量图片,采用方式:使用时加载,不显示时直接置null或recycle。

这样处理是个好习惯,基本上可以杜绝OOM。但是缺憾是代码多了,可能会忘记某些资源recycle。而且有些情况下会出现特定的图片反复加载、释放、再加载等,低效率的事情。

2,简单通过SoftReference引用方式管理图片资源

建个SoftReference的hashmap;

使用图片时先查询这个hashmap是否有SoftReference,SoftReference里的图片是否空;

如果空就加载图片到SoftReference并加入hashmap。

无需在代码里显式的处理图片的回收和释放,gc会自动处理资源的释放。

这种方式处理起来简单实用,能一定程度上避免前一种方法反复加载释放的低效率。但还不够优化。

3,强引用+软引用二级缓

Android示范程序ImageDownloader.java,使用了一个二级缓存机制。就是有一个数据结构中直接持有解码成功的Bitmap对象引用,同时使用一个二级缓存数据结构保持淘汰的Bitmap对象的SoftReference对象,由于SoftReference对象的特殊性,系统会在需要内存的时候首先将SoftReference 对象持有的对象释放掉,也就是说当VM发现可用内存比较少了需要触发GC的时候,就会优先将二级缓存中的Bitmap回收,而保有一级缓存中的Bitmap对象用于显示。

其实这个解决方案最为关键的一点是使用了一个比较合适的数据结构,那就是LinkedHashMap类型来进行一级缓存Bitmap的容器,由于LinkedHashMap的特殊性,我们可以控制其内部存储对象的个数并且将不再使用的对象从容器中移除,放到SoftReference二级缓存里,我们可以在一级缓存中一直保存最近被访问到的Bitmap对象,而已经被访问过的图片在LinkedHashMap的容量超过我们预设值时将会把容器中存在时间最长的对象移除,这个时候我们可以将被移除出LinkedHashMap中的对象存放至二级缓存容器中,而二级缓存中对象的管理就交给系统来做了,当系统需要GC时就会首先回收二级缓存容器中的Bitmap对象了。

在获取图片对象的时候先从一级缓存容器中查找,如果有对应对象并可用直接返回,如果没有的话从二级缓存中查找对应的SoftReference对象,判断SoftReference对象持有的Bitmap是否可用,可用直接返回,否则返回空。如果2级缓存都找不到图片,就直接加载图片资源。

private static final int HARD_CACHE_CAPACITY = 16;

// Hard cache, with a fixed maximum capacity and a life duration

private static final HashMap sHardBitmapCache = new LinkedHashMap(HARD_CACHE_CAPACITY, 0.75f, true) {

private static final long serialVersionUID = -57738079457331894L;

@Override

protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) {

if(size() > HARD_CACHE_CAPACITY) {

sSoftBitmapCache.put(eldest.getKey(), new SoftReference(eldest.getValue()));

return true;

} else

return false;

}

};

// Soft cache for bitmap kicked out of hard cache

private final static ConcurrentHashMap> sSoftBitmapCache = new ConcurrentHashMap>(HARD_CACHE_CAPACITY);

public Bitmap getBitmap(String id) {

// First try the hard reference cache

synchronized(sHardBitmapCache) {

final Bitmap bitmap = sHardBitmapCache.get(id);

if(bitmap != null) {

// Bitmap found in hard cache

// Move element to first position, so that it is removed last

sHardBitmapCache.remove(id);

sHardBitmapCache.put(id, bitmap);

return bitmap;

} else{

// Then try the soft reference cache

SoftReference bitmapReference = sSoftBitmapCache.get(id); if(bitmapReference != null) {

final Bitmap bitmap = bitmapReference.get();

if(bitmap != null) {

// Bitmap found in soft cache

return bitmap;

} else{

// Soft reference has been Garbage Collected

sSoftBitmapCache.remove(id);

}

}

}

}

return null;

}

public void putBitmap(String id, Bitmap bitmap) {

synchronized(sHardBitmapCache) {

if(sHardBitmapCache != null) {

sHardBitmapCache.put(id, bitmap);

}

}

}

4,LruCache +sd的缓存方式

LruCache 类特别合适用来caching bitmaps;

private LruCache mMemoryCache;

@Override

protected void onCreate(Bundle savedInstanceState) { ...

// Get memory class of this device, exceeding this amount will throw an

// OutOfMemory exception.

final int memClass = ((ActivityManager) context.getSystemService(

Context.ACTIVITY_SERVICE)).getMemoryClass();

// Use 1/8th of the available memory for this memory cache.

final int cacheSize = 1024 * 1024 * memClass / 8;

mMemoryCache = new LruCache(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap bitmap) {

// The cache size will be measured in bytes rather than number of items.

return bitmap.getByteCount();

}

};

...

}

public void addBitmapToMemoryCache(String key, Bitmap bitmap) {

if (getBitmapFromMemCache(key) == null) {

mMemoryCache.put(key, bitmap);

}

}

public Bitmap getBitmapFromMemCache(String key) {

return mMemoryCache.get(key);

}

当加载位图到ImageView时,LruCache会先被检查是否存在这张图片。如果找到有,它会被用来立即更新ImageView 组件,否则一个后台线程则被触发去处理这张图片。

public void loadBitmap(int resId, ImageView imageView) {

final String imageKey = String.valueOf(resId);

final Bitmap bitmap = getBitmapFromMemCache(imageKey);

if (bitmap != null) {

mImageView.setImageBitmap(bitmap);

} else { mImageView.setImageResource(R.drawable.image_placeholder); //默认图片

BitmapWorkerTask task = new BitmapWorkerTask(mImageView);

task.execute(resId);

}

}

上面的程序中BitmapWorkerTask 也需要做添加到内存Cache中的动作:

class BitmapWorkerTask extends AsyncTask {

...

// Decode image in background.

@Override

protected Bitmap doInBackground(Integer... params) {

final Bitmap bitmap = decodeSampledBitmapFromResource(

getResources(), params[0], 100, 100));

addBitmapToMemoryCache(String.valueOf(params[0]), bitmap);

return bitmap;

}

...

}

Use a Disk Cache [使用磁盘缓存]

private DiskLruCache mDiskCache;

private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB private static final String DISK_CACHE_SUBDIR = "thumbnails";

@Override

protected void onCreate(Bundle savedInstanceState) {

...

// Initialize memory cache

...

File cacheDir = getCacheDir(this, DISK_CACHE_SUBDIR);

mDiskCache = DiskLruCache.openCache(this, cacheDir, DISK_CACHE_SIZE); ...

}

class BitmapWorkerTask extends AsyncTask {

...

// Decode image in background.

@Override

protected Bitmap doInBackground(Integer... params) {

final String imageKey = String.valueOf(params[0]);

// Check disk cache in background thread

Bitmap bitmap = getBitmapFromDiskCache(imageKey);

if (bitmap == null) { // Not found in disk cache

// Process as normal

final Bitmap bitmap = decodeSampledBitmapFromResource(

getResources(), params[0], 100, 100));

}

// Add final bitmap to caches

addBitmapToCache(String.valueOf(imageKey, bitmap);

return bitmap;

}

...

}

public void addBitmapToCache(String key, Bitmap bitmap) {

// Add to memory cache as before

if (getBitmapFromMemCache(key) == null) {

mMemoryCache.put(key, bitmap);

}

// Also add to disk cache

if (!mDiskCache.containsKey(key)) {

mDiskCache.put(key, bitmap);

}

}

public Bitmap getBitmapFromDiskCache(String key) {

return mDiskCache.get(key);

}

// Creates a unique subdirectory of the designated app cache directory. Tries to use external

// but if not mounted, falls back on internal storage.

public static File getCacheDir(Context context, String uniqueName) {

// Check if media is mounted or storage is built-in, if so, try and use external cache dir

// otherwise use internal cache dir

final String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED

|| !Environment.isExternalStorageRemovable() ?

context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();

return new File(cachePath + File.separator + uniqueName);

}

两种场景下的图片加载建议:

1,网络下载大量图片

比如微博客户端:

多线程异步网络下载图片,小图直接用LRUcache+softref+sd卡,大图按需下载;

2,对于需要展现非常多条目信息的listview、gridview等的情况

在adapter的getview函数里有个convertView参数,告知你是否有课利旧的view对象。如果不使用利旧convertView的话,每次调用getView时每次都会重新创建View,这样之前的View可能还没有销毁,加之不断的新建View势必会造成内存泄露。同时利旧convertView时,里面原有的图片等资源就会变成无主的了。

推介使用convertView+静态类ViewHolder。

在这里,官方给出了解释

提升Adapter的两种方法

重用缓存convertView传递给getView()方法来避免填充不必要的视图

使用ViewHolder模式来避免没有必要的调用findViewById():因为太多的findViewById也会影响性能

ViewHolder类的作用

ViewHolder模式通过getView()方法返回的视图的标签(Tag)中存储一个数据结构,这个数据结构包含了指向我们

要绑定数据的视图的引用,从而避免每次调用getView()的时候调用findViewById())

远远超过限制的内存分配方式有两种:

1,是从本机代码分配内存。使用NDK(本地开发工具包)和JNI,它可能从C级(如的malloc /

free或新建/删除)分配内存,这样的分配是不计入对24 MB的限制。这是真的,从本机代码分配内存是为从Java方便,但它可以被用来存储在RAM中的数据(即使图像数据)的一些大金额。

2,使用OpenGL的纹理-纹理内存不计入限制,要查看您的应用程序确实分配多少内存可以使用android.os.Debug.getNativeHeapAllocatedSize(),可以使用上面介绍的两种技术的Nexus之一,我可以轻松地为一个单一的前台进程分配300MB - 10倍以上的默认24 MB的限制,从上面来看使用navtive代码分配内存是不在24MB的限制内的(开放的GL的质地也是使用navtive代码分配内存的)。

但是,这2个方法有个风险就是,本地堆分配内存超过系统可用内存限制的话,通常都是直接崩溃。

使用效率要提高内存优化方法集合

内存对我们来说,作用很大,一个电脑的内存使用效率如何决定了它的运行质量,因此如何优化内存的管理,提高内存的使用效率,尽可能地提高运行速度,是我们所关心的问题。下面介绍在Windows操作系统中,提高内存的使用效率和优化内存管理的几种方法。 1、改变页面文件的位置 其目的主要是为了保持虚拟内存的连续性。因为硬盘读取数据是靠磁头在磁性物质上读取,页面文件放在磁盘上的不同区域,磁头就要跳来跳去,自然不利于提高效率。而且系统盘文件众多,虚拟内存肯定不连续,因此要将其放到其他盘上。改变页面文件位置的方法是:用鼠标右键点击“我的电脑”,选择“属性→高级→性能设置→高级→更改虚拟内存”,在驱动器栏里选择想要改变到的位置即可。值得注意的是,当移动好页面文件后,要将原来的文件删除(系统不会自动删除)。 2、改变页面文件的大小 改变了页面文件的位置后,我们还可以对它的大小进行一些调整。调整时我们需要注意,不要将最大、最小页面文件设为等值。因为通常内存不会真正“塞满”,它会在内存储量到达一定程度时,自动将一部分暂时不用的数据放到硬盘中。最小页面文件越大,所占比例就低,执行的速度也就越慢。最大页面文件是极限值,有时打开很多程序,内存和最小页面文件都已“塞满”,就会自动溢出到最大页面文件。所以将两者设为等值是不合理的。一般情况下,最小页面文件设得小些,这样能在内存中尽可能存储更多数据,效率就越高。最大页面文件设得大些,以免出现“满员”的情况。 3、禁用页面文件 当拥有了512MB以上的内存时,页面文件的作用将不再明显,因此我们可以将其禁用。方法是:依次进入注册表编辑器“HKEY_LOCAL_MACHINESystemCurrentControlSetControlS

Android 应用程序内存泄漏的分析

Android 应用程序内存泄漏的分析以前在学校里学习Java的时候,总是看到说,java是由垃圾收集器(GC)来管理内存回收的,所以当时形成的观念是Java不会产生内存泄漏,我们可以只管去申请内存,不需要关注内存回收,GC会帮我们完成。呵呵,很幼稚的想法,GC没那么聪明啊,理论及事实证明,我们的Java程序也是会有内存泄漏的。 (一)Java内存泄漏从何而来 一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,没有将其释放,或者是在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。 (二)需要的工具 1.DDMS—Update heap Gause GC Heap 是DDMS自带的一个很不错的内存监控工具,下图红色框中最左边的图标就是该 工具的启动按钮,它能在Heap视图中显示选中进程的当前内存使用的详细情况。下图 框中最右边的是GC工具,很多时候我们使用Heap监控内存的时候要借助GC工具,点 击一次GC按钮就相当于向VM请求了一次GC操作。中间的按钮是Dump HPROF file,它 的功能相当于给内存拍一张照,然后将这些内存信息保存到hprof文件里面,在使用我 们的第二个工具MAT的时候会使用到这个功能。 2.MAT(Memory Analyzer Tool) Heap工具能给我们一个感性的认识,告诉我们程序当前的内存使用情况和是否存在内存 泄漏的肯能性。但是,如果我们想更详细,更深入的了解内存消耗的情况,找到问题所 在,那么我们还需要一个工具,就是MAT。这个工具是需要我们自己去下载的,可以下 载独立的MAT RCP 客户端,也可以以插件的形式安装到Eclipse里面,方便起见,推荐 后者。 安装方法: A.登录官网https://www.360docs.net/doc/d117564923.html,/mat/downloads.php B.下载MAT Eclipse插件安装包(红框所示,当然你也可是选择Update Site在线安装,个人觉得比较慢)

Windows虚拟内存优化设置专题

Windows虚拟内存优化设置专题 编辑手记 虚拟内存是文件数据交叉链接的活动文件。是WINDOWS目录下的一个"WIN386.SWP"文件,这个文件会不断地扩大和自动缩小。 就速度方面而言,CPU的L1和L2缓存速度最快,内存次之,硬盘再次之。但是虚拟内存使用的是硬盘的空间,为什么我们要使用速度最慢的硬盘来做为虚拟内存呢?因为电脑中所有运行的程序都需要经过内存来执行,如果执行的程序很大或很多,就会导致我们只有可怜的256M/512M内存消耗殆尽。而硬盘空间动辄几十G上百G,为了解决这个问题,Windows中运用了虚拟内存技术,即拿出一部分硬盘空间来充当内存使用... 如何设置虚拟内存 当你游戏玩得正酣,或者在激情冲浪开启多个窗口时,你的系统总会出现“虚拟内存不足”的提示。机器此时慢如蜗牛,刚才好的心情顿时没了。这一问题引起许多新手朋友的兴趣,这是他们经常遇到的情况。虚拟内存的作用是什么?到底设置多少为好? Windows XP虚拟内存的标准设置方法虚拟内存让系统更流畅 虚拟内存的作用手动设置虚拟内存 透析虚拟内存 虚拟内存优化设置 虚拟内存对于任何版本的Windows而言都是十分重要的。如果设置得当,它将极大地提升电脑的性能和运行速度。可是在默认状态下,Windows始终将虚拟内存设为物理内存的1.5倍。这样的话,如果用户安装2GB的内存,系统就会腾出高达3GB的硬盘空间作为虚拟内存。但以当前的主流应用软件和游戏对内存的需要来看,根本没有必要使用这么多的虚拟内存。那么,有没有什么秘技或绝招可使虚拟内存运用得更有效率或更显性能呢? 1、改变页面文件的位置 2、改变页面文件的大小 3、启用磁盘写入缓存 4、打开Ultra MDA 5、清空页面文件 6、启用系统缓存 细说Windows XP 虚拟内存优化虚拟内存页面文件的大小计算 Windows系统虚拟内存加速密籍摆脱限制使有限的内存用在刀刃上 Win2000虚拟内存优化设置谈再谈谈虚拟内存如何设置为好 新手入门:双系统巧共享虚拟内存Windows虚拟内存常见问题解决方法 “虚拟内存不够”的几个可能 我用的电脑系统是WinXP,最近使用时,没开多少程序,却常常出现“虚拟内存不足”的系统提示。这是什么原因造成的呢? 1、感染病毒 2、虚拟内存设置不当 3、系统空间不足 4、因为SYSTEM用户权限设置不当 Windows“虚拟内存不够”的几个可能

数据库-SQL Server 2014 新特性之内存优化表--嘉为科技

方勇 【摘要】 2013年6月25日,微软发布了SQL Server 2014 CTP1。本文将为您介绍SQL Server 2014 的重点新特性——内存优化表。 【正文】 如果说SQL Server 2012 的数据库引擎最大的亮点是Always On的话,那么SQL Server 2014 最大的亮点就是内存优化表(Memory-optimized tables)了。 1. 内存表的背景 在SQL Server 2000 的年代,我们还可以通过这种方式,将表驻留在内存中:DBCC PINTABLE ( database_id , table_id ) DBCC PINTABLE 会导致将表读入到内存中。当表中的页由普通的Transact-SQL 语句读入到高速缓存中时,这些页将标记为内存驻留页。当SQL Server 需要空间以读入新页时,不会清空内存驻留页。 但是这种方式在SQL Server 2005 已经不被支持了,内存表这种概念消失了,直到SQL Server 2014。 2. 文件和存储 内存优化表必须存储到文件流文件组中,SQL Server 提供了一种MEMORY_OPTIMIZED_DATA 文件组类型专门用于指定内存优化表的逻辑存储位置。 内存优化表的文件流文件组可以包含一个或多个容器,每个容器有可以包含一个或多个 文件。文件包含了三种类型的文件:

●根文件(Root File):包含了数据文件和增量文件的元数据 ●数据文件(Data File):存储内存优化表的记录和新插入的记录 ●增量文件(Delta File):按照事务日志顺序存储从内存优化表中删除的记录的 最小信息(行号),每个数据文件对应一个增量文件 内存优化表会使用到事务日志,同样任何增删改等操作都会写入日志,这可能是导致即使使用内存优化表,性能也无法显著提升的最大原因,可以考虑使用闪存或者SSD来解决该问题 3. 原理和机制 SQL Server 2014 新增的内存优化表让我们眼前一亮,可以改善基于磁盘的表的低性能。通过以下的原理和机制让我们获得更好的性能和可扩缩性: ●通过数据页和索引页驻留在内存,减少IO瓶颈 ●采用乐观并发控制,消除了逻辑锁,提高了并发性 ●本机编译存储过程,执行效率更高 我们一定会担心,使用内存优化表会不会导致因为驻留在内存中,系统宕机或者断电的时候,导致数据无法及时写回内存而丢失。内存优化表保留了关系型数据库的事务所有ACID 特征:原子性、一致性、隔离性和持久性。SQL Server和内存优化表的持久化上下文提供了以下保证: ●事务持久化:提交DDL或DML更改内存优化表的事务,更改是永久性的(不 丢失); ●重启持久化:在系统崩溃恢复或计划重新启动后,内存优化表重新实例化以恢 复到关闭或崩溃时的状态; ●介质失败持久化:当磁盘损坏时,我们可以通过数据库的备份和还原来恢复内 存优化表到新存储 当然,内存优化表有两种持久化选项,其中有一种是不保证持久化的: ●SCHEMA_ONLY(非持久化表):只持久化表结构和索引,重启后所有数据丢

电脑内存太小的优化方法步骤

电脑内存太小的优化方法步骤 导读:我根据大家的需要整理了一份关于《电脑内存太小的优化方法步骤》的内容,具体内容:当买一台电脑了,安装很多的软件程序,就会占很多的游戏,电脑当时配置也不高,内存不够用了,就会提出内存不够,电脑内存太小怎么解决呢?下面我就为大家带来了XP系统内存优化的方法。电... 当买一台电脑了,安装很多的软件程序,就会占很多的游戏,电脑当时配置也不高,内存不够用了,就会提出内存不够,电脑内存太小怎么解决呢?下面我就为大家带来了XP系统内存优化的方法。 电脑内存太小解决方法一 1、改变页面文件的位置 其目的主要是为了保持虚拟内存的连续性。因为硬盘读取数据是靠磁头在磁性物质上读取,页面文件放在磁盘上的不同区域,磁头就要跳来跳去,自然不利于提高效率。而且系统盘文件众多,虚拟内存肯定不连续,因此要将其放到其他盘上。改变页面文件位置的方法是:用鼠标右键点击"我的电脑",选择"属性高级性能设置高级更改虚拟内存",在驱动器栏里选择想要改变到的位置即可。值得注意的是,当移动好页面文件后,要将原来的文件删除(系统不会自动删除)。 2、禁用页面文件 当拥有了512MB以上的内存时,页面文件的作用将不再明显,因此我们可以将其禁用。方法是:依次进入注册表编辑器

"HKEY_LOCAL_MACHINESystemCurrentControlSetControlSession Ma-nagerMemoryManagement"下,在"DisablePa-ging Executive"(禁用页面文件)选项中将其值设为"1"即可。 3、清空页面文件 在同一位置上有一个"ClearPageFileAtShutdown(关机时清除页面文件)",将该值设为"1"。这里所说的"清除"页面文件并非是指从硬盘上完全删除pagefile.sys文件,而是对其进行"清洗"和整理,从而为下次启动Windows XP时更好地利用虚拟内存做好准备。 4、及时释放内存空间 如果你发现系统的内存不多了,就要注意释放内存。所谓释放内存,就是将驻留在内存中的数据从内存中释放出来。释放内存最简单有效的方法,就是重新启动计算机。另外,就是关闭暂时不用的程序。还有要注意剪贴板中如果存储了图像资料,是要占用大量内存空间的。这时只要剪贴几个字,就可以把内存中剪贴板上原有的图片冲掉,从而将它所占用的大量的内存释放出来。 5、优化内存中的数据 在Windows中,驻留内存中的数据越多,就越要占用内存资源。所以,桌面上和任务栏中的快捷图标不要设置得太多。如果内存资源较为紧张,可以考虑尽量少用各种后台驻留的程序。平时在操作电脑时,不要打开太多的文件或窗口。长时间地使用计算机后,如果没有重新启动计算机,内存中的数据排列就有可能因为比较混乱,从而导致系统性能的下降。这时你就要考虑重新启动计算机。

android如何查看cpu的占用率和内存泄漏

android如何查看cpu的占用率和内存泄漏 在分析内存优化的过程中,其中一个最重要的是我们如何查看cpu的占用率和内存的占用率呢,这在一定程度上很重要,经过查询资料,研究了一下,暂时了解到大概有以下几种方式,如果哪位高手有更好的办法,或者文中描述有错误,还望高手在下面留言,非常感谢! 一、通过eclipse,ADT开发工具的DDMS来查看(Heap) 在“Devices”窗口中选择模拟器中的一个需要查看的程序,从工具条中选“Update heap”按钮,给这个程序设置上“heap Updates”,然后在Heap视图中点击Cause GC就可以实时显示这个程序的一些内存和cpu的使用情况了。

然后就会出现如下界面: 说明: a) 点击“Cause GC”按钮相当于向虚拟机请求了一次gc操作; b) 当内存使用信息第一次显示以后,无须再不断的点击“Cause GC”,Heap视图界面会定

时刷新,在对应用的不断的操作过程中就可以看到内存使用的变化; c) 内存使用信息的各项参数根据名称即可知道其意思,在此不再赘述。 大致解析如下: 这个就是当前应用的内存占用,allocated 是已经分配的内存free是空闲内存, heap size 是虚拟机分配的不是固定值 heap size 的最大值跟手机相关的 有网友说, 一般看1byte的大部分就是图片占用的 如何判断应用是否有内存泄漏的可能性呢? 如何才能知道我们的程序是否有内存泄漏的可能性呢。这里需要注意一个值:Heap视图中部有一个Type叫做data object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。可以这样判断: a) 不断的操作当前应用,同时注意观察data object的Total Size值; b) 正常情况下Total Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平; c) 反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC 后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大, 直到到达一个上限后导致进程被kill掉。

网络性能优化

网络性能优化总结 网络性能优化的目的是减少网络系统的瓶颈、设法提高网络系统的运行效率。对于不同的网络硬件环境和软件环境,可以存在不同的优化方法和内容。例如,在一个配置比较落 后而又需要提供各种新服务的网络中,管理员往往需要对内存、CPU磁盘、网络接口和服 务器等分别进行优化处理,以便适应新的网络运行要求。但是,在一个网络服务比较少而硬 件配置比较高的网络中,管理员不需要考虑整个网络的性能问题,只要利用一些性能和网络 监视工具对系统进行监视,然后对发现的问题进行专项处理即可。下面对网络性能优化过程 中的重要内容分别进行介绍。 721内存优化 内存是操作系统中的重要资源,不仅操作系统的运行需要它,而且各种应用程序和服务都需要调用它才能使用。从应用的角度来看,系统内存是引起各种系统问题的重要原因,是需要用户和管理员着重考虑的优化对象。 1.合理使用内存 在内存一定的情况下,合理地使用内存可以提高网络的性能。这要求管理员必须对系 统中的内存使用情况非常了解,对于那些不再需要的功能、应用程序或服务应及时关闭,以便释放内存给其他应用程序和服务。另外,管理员还可以通过系统设置来决定内存的主要优 化对象。一般,服务器的主要优化对象应该是后台服务,而工作站和单个计算机的主要优化 对象应该是前台应用程序。 要选择内存优化的主要对象,可执行下面的操作步骤: (1)打开“控制面板”窗口,右击“系统”图标,从弹出的快捷菜单中选择“打开” 命令,打开“系统特性”对话框。 (2)单击“高级”标签,切换到“高级”选项卡,然后单击“性能”选项组中的“性 能选项”按钮,打开“性能选项”对话框,如图7-1所示。 图7-1 “性能选项”对话框

嵌入式内存优化

嵌入式内存优化 姓名:汪如胜 学号:1215115032 班级:移动一班 专业:软件工程

嵌入式安全使用内存 对于任何一个应用程序,其内存使用的方式都对整个程序的运行效率、稳定性有重大的影响。例如:对于资源紧张的嵌入式系统,如果编写的程序造成内存泄露,运行的初始阶段可以正常运行,但是当因内存泄露的积累而造成内存资源耗尽时,该应用程序便会崩溃;如果是一个资源相对丰富的嵌入式系统,引起内存泄露的应用程序可能可以稳定运行较长时间后才出现资源耗尽情况,此种情况在测试应用程序时期难以发现,但对实际应用会有重大影响。 一般来讲,Linux 的内存的分配方式有以下几种: 1、从静态存储区域分配:该部分内存在程序编译的时候已经分配完成,在程序的整个运行期间都存在,一般用于全局变量。 2、从栈分配:一般来讲,函数内的局部变量的存储单元都可在栈上创建,函数执行完成后,相应的存储单元会自动释放。栈内存分配功能内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 3、从堆分配:该种分配方式就是所谓的动态内存分配,使用该种分配方式是提高程序效率的基础。该部分内存需要程序员使用

malloc 或者new 来申请任意大小的内存,同时,程序员必须负责在内存使用完成后用free 或者delete 来释放内存,使用非常灵活,但是很容易出现问题,实际上,应用程序使用内存出现的问题几乎都出在该种分配方式上。 在使用动态内存的过程中,一定要先保证内存能够成功的分配,即在使用内存之前首先要检查该内存指针是否为NULL;同时,若该内存区域可以使用,则使用前一定要对该区域内存进行初始化,因为内存的默认初值目前还没有统一的标准。 内存在正常使用中,一定要防止操作越过内存的边界,即所谓的内存溢出。内存溢出容易使程序运行紊乱,并且可能直接导致应用程序崩溃。在内存使用完成后,必须使用相应的语句来释放该部分内存,否则该部分内存即产生内存泄露。 在实际的代码书写过程中,可以通过查询分配内存语句和释放内存语句的个数来检查是否存在内存泄露。若分配内存的操作次数和释放内存的操作次数相等,则内存一般不会产生泄露,若不相等,则内存肯定存在泄露,必须查明原因,修改相应代码,否则该应用程序很可能会出现问题。 性能分析

MySQL内存及虚拟内存优化设置

为了装mysql环境测试,装上后发现启动后mysql占用了很大的虚拟内存,达8百多兆。网上搜索了一下,得到高人指点my.ini。再也没见再详细的了..只好打开my.ini逐行的啃,虽然英文差了点,不过多少M还是看得明的^-^ 更改后如下: innodb_buffer_pool_size=576M ->256M InnoDB引擎缓冲区占了大头,首要就是拿它开刀query_cache_size=100M ->16M 查询缓存 tmp_table_size=102M ->64M 临时表大小 key_buffer_size=256m ->32M 重启mysql服务后,虚拟内存降到200以下. 另外mysql安装目录下有几个文件:my-huge.ini 、my-large.ini、my-medium.ini...这几个是根据内存大小作的建议配置,新手在设置的时候也可以参考一下。 2G内存的MYSQL数据库服务器my.ini优化(my.ini) 2G内存,针对站少,优质型的设置,试验特: table_cache=1024 物理内存越大,设置就越大.默认为2402,调到512-1024最佳 innodb_additional_mem_pool_size=8M 默认为2M innodb_flush_log_at_trx_commit=0 等到innodb_log_buffer_size列队满后再统一储存,默认为1 innodb_log_buffer_size=4M 默认为1M innodb_thread_concurrency=8 你的服务器CPU有几个就设置为几,默认为8 key_buffer_size=256M 默认为218 调到128最佳 tmp_table_size=64M 默认为16M 调到64-256最挂 read_buffer_size=4M 默认为64K read_rnd_buffer_size=16M 默认为256K sort_buffer_size=32M 默认为256K max_connections=1024 默认为1210 试验一: table_cache=512或1024 innodb_additional_mem_pool_size=2M innodb_flush_log_at_trx_commit=0 innodb_log_buffer_size=1M innodb_thread_concurrency=8 你的服务器CPU有几个就设置为几,默认为8 key_buffer_size=128M tmp_table_size=128M read_buffer_size=64K或128K

安卓性能优化方案

随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要求远远高于PC的桌面应用程序。以上理由,足以需要开发人员更加专心去实现和优化你的代码了。选择合适的算法和数据结构永远是开发人员最先应该考虑的事情。同时,我们应该时刻牢记,写出高效代码的两条基本的原则:(1)不要做不必要的事;(2)不要分配不必要的内存。 我从去年开始接触Android开发,以下结合自己的一点项目经验,同时参考了Google的优化文档和网上的诸多技术大牛给出的意见,整理出这份文档。 1. 内存优化 Android系统对每个软件所能使用的RAM空间进行了限制(如:Nexus o ne 对每个软件的内存限制是24M),同时Java语言本身比较消耗内存,d alvik虚拟机也要占用一定的内存空间,所以合理使用内存,彰显出一个程序员的素质和技能。 1) 了解JIT 即时编译(Just-in-time Compilation,JIT),又称动态转译(Dynamic Translation),是一种通过在运行时将字节码翻译为机器码,从而改善字节码编译语言性能的技术。即时编译前期的两个运行时理论是字节码编译和动态编译。Android原来Dalvik虚拟机是作为一种解释器实现,新版

(Android2.2+)将换成JIT编译器实现。性能测试显示,在多项测试中新版本比旧版本提升了大约6倍。 详细请参考https://www.360docs.net/doc/d117564923.html,/cool_parkour/blog/item/2802b01586e22cd8a6ef3f6b. html 2) 避免创建不必要的对象 就像世界上没有免费的午餐,世界上也没有免费的对象。虽然gc为每个线程都建立了临时对象池,可以使创建对象的代价变得小一些,但是分配内存永远都比不分配内存的代价大。如果你在用户界面循环中分配对象内存,就会引发周期性的垃圾回收,用户就会觉得界面像打嗝一样一顿一顿的。所以,除非必要,应尽量避免尽力对象的实例。下面的例子将帮助你理解这条原则: 当你从用户输入的数据中截取一段字符串时,尽量使用substring函数取得原始数据的一个子串,而不是为子串另外建立一份拷贝。这样你就有一个新的String对象,它与原始数据共享一个char数组。如果你有一个函数返回一个String对象,而你确切的知道这个字符串会被附加到一个Stri ngBuffer,那么,请改变这个函数的参数和实现方式,直接把结果附加到StringBuffer中,而不要再建立一个短命的临时对象。 一个更极端的例子是,把多维数组分成多个一维数组: int数组比Integer数组好,这也概括了一个基本事实,两个平行的int数组比(int,int)对象数组性能要好很多。同理,这试用于所有基本类型的组合。如果你想用一种容器存储(Foo,Bar)元组,尝试使用两个单独的Foo[]

电脑怎么优化内存

电脑怎么优化内存 当运行很多程序时,电脑速度会很降下来不少,如果电脑性能差,内存小的电脑更是会很卡很慢,这时,可以通过优化电脑内存来提高主要程序的运行速度,那么电脑怎么优化内存呢?下面跟着小编一起来了解一下吧。 电脑优化内存方法 1. 调整高速缓存区域的大小 可以在“计算机的主要用途”选项卡中设置系统利用高速缓存的比例。如果系统的内存较多,可选择“网络服务器”,这样系统将用较多的内存作为高速缓存。在CD-ROM标签中,可以直接调节系统用多少内存作为CD-ROM光盘读写的高速缓存。 2. 监视内存 系统的内存不管有多大,总是会用完的。虽然有虚拟内存,

但由于硬盘的读写速度无法与内存的速度相比,所以在使用内存时,就要时刻监视内存的使用情况。Windows操作系统中提供了一个系统监视器,可以监视内存的使用情况。一般如果只有60%的内存资源可用,这时你就要注意调整内存了,不然就会严重影响电脑的运行速度和系统性能。 3. 及时释放内存空间 如果你发现系统的内存不多了,就要注意释放内存。所谓释放内存,就是将驻留在内存中的数据从内存中释放出来。释放内存最简单有效的方法,就是重新启动计算机。另外,就是关闭暂时不用的程序。还有要注意剪贴板中如果存储了图像资料,是要占用大量内存空间的。这时只要剪贴几个字,就可以把内存中剪贴板上原有的图片冲掉,从而将它所占用的大量的内存释放出来。 4. 改变页面文件的大小 改变了页面文件的位置后,我们还可以对它的大小进行一些调整。调整时我们需要注意,不要将最大、最小页面文件设为等值。因为通常内存不会真正“塞满”,它会在内存储量到达一定程度时,自动将一部分暂时不用的数据放到硬盘中。最小页面文件越大,所占比例就低,执行的速度也就越慢。最大页面文件是极限值,有时打开

优化你的手机内存(总结篇)

优化你的手机内存(总结篇) 优化你的手机,让你的手机性能更加的强劲,appman完善版的使用教程 优化你的手机,让你的手机性能更加的强劲,appman的使用教程 优化手机、保持大内存的方法(APPMAN的使用技巧) 别忘记用压缩包的汉化文件appman.rsc覆盖掉安装目录里的同名文件,就可以正确显示中文了 一、首先需要清楚内存和手机存储空间的区别 系统速度、程序运行的快慢主要看内存(RAM)的大小,这和电脑上的内存是一致的。内存小则速度慢,甚至一些需要大内存的游戏和软件无法运行出现OUT MEMERY的提示。这个和系统的运行内存有关的,和C盘和E盘MMC卡的容量无关,即 使你的MMC卡上还有几百MB的空间也没用,我们需要解决的是释放被程序占用运行 内存,让运行内存尽可能的大。 二、怎么看系统的运行内存 很多人会用SELEQ等文件管理来看,这样看是看不到的,看到的只是存储空间 的大小。 运行内存一般使用APPMAN来看。打开APPMAN,就可以在左上角看到系统剩余 的内存大小了。除去3650,7610/6600剩余内存应该有8、9MB的,NG的话应该有 10MB以上,QD更大因为不需要中文字体占用空间。。如果只有5、6MB的话,那你 的手机就是简直给你蹂躏的不象样子了。 三、释放内存基础篇 1、刚开机的时候的内存是最大的,所以一般重新开机可以达到手机现有状态 下的最大的内存 2、打开APPMAN,进行压缩,也可以释放一部分内存,但非常有限

3、如果你刚开机后的内存都非常小,那么就需要优化你的机器了 优化有如下方法: 1)如果你的机器太乱了,那么最好格式化你的机器,保持最干净的系统,你也可 以看看这个时候你的最大内存是多少。 2)尽量少装开机自启动的软件,这些软件开机就自动运行并且常驻内存,例如: 来电大头贴、防火墙、增强情景模式、自动锁键盘等等。 3)尽量不要装其它字体文件。字体文件开机也会加载到内存中,而且字体容量比较大,一下就会出掉很多内存。 四、优化内存高级篇 1、APPMAN进入,向左第三个选项卡“线程”里可进行手动释放内存。“线程”里可以看到所有正在内存里调用的程序,向左第四个选项卡“文档”里可以看 见所有调用的文本和字体文件。这些都是占用内存的。 这些线程分两种,一种是手机自带的,一种是后来安装的。 手机自带的线程后面都会有一个齿轮,没有齿轮的就是第三方线程。 没有齿轮的都可以关闭,点左功能键——工具——关闭选定程序即可。关闭后相应程序需要重新开启后才能使用。点右功能键“详情”可知道此线程的具体 情况和安装路径,如果不需要的话,你也可关闭后在程序管理器中卸载。 选项卡“文档”里如果有看见其它安装的字体文件,那吃掉的内存就比较多了。 2、有齿轮的一般是手机自带的程序,如果不清楚作用的话,最好不要随便关 闭,关闭后可能导致手机的部分功能不能使用或手机出错重新启动。 因为系统自带程序即使关闭后下次启动还会运行,所以一般只在有特殊需要的时候才使用。 五、垃圾清理工作 此操作不在内存优化之列。只是APPMAN附带说一下的功能之一。向左第五个 选项卡“安装程序”列表,看见程序后面有垃圾筒标记的,都是没有用的垃圾文 件可以删除。此法可清理手机里遗留的一部分垃圾文件。

谈51单片机内存优化

Keil C51内存分配与优化 分类:C/C++单片机 2012-01-06 19:10 272人阅读评论(0) 收藏举报 C51的内存分配不同于一般的PC,内存空间有限,采用覆盖和共享技术。在Keil编译器中,经过编译后,会形成一个M51文件,在其内部可以详细的看到内存的分配情况。 C51内存常见的两个误区: (1)变量超过128字节后必须用COMPACT模式。 其实,只要不超过256字节,都可以用SMALL模式 (2)内部RAM,128字节以上的是SFR用,不给程序用。 其实,由于C51寻址的不同,高128字节也可以用来存储变量,虽与SFR地址相同,但寻址的方式不同。 下面通过几个程序来看内存的分配。 ******************************************************************************* //程序1: #include void main() {} Program Size: data=9.0 xdata=0 code=16 TYPE BASE LENGTH RELOCATION SEGMENT NAME ----------------------------------------------------- * * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" IDATA 0008H 0001H UNIT ?STACK ******************************************************************************* 从上面可以看到,即使程序内部无任何变量和函数data也会为9.0。这9个字节内存分别为R0-R8和一个堆栈指针(C51的堆栈是“grow up”,即使堆栈中没有内容,也会有一个栈底指针)。data区中由于R0-R8占有8个存储空间,因此data区最大为120字节(栈在所有的变量空间之后),如果超过120个字节则由idata显式的指定为间接寻址。对于整个内部256字节的RAM,在极端的情况下,最大的变量为247字节。 当定义全局变量时 ******************************************************************************* //程序2: #include #define uint unsigned int #define uchar unsigned char

Android内存优化小建议 以及活用(SoftReference 和 WeakReference )

android因其系统的特殊性,安装的软件默认都安装到内存中,所以随着 用户安装的软件越来越多,可供运行的程序使用的内存越来越小,这就要求我们在开发android程序时,尽可能的少占用内存。根据我个人的开发经验总结了如下几点优化内存的方法: 1创建或其他方式获得的对象如不再使用,则主动将其置为null。 2尽量在程序中少使用对图片的放大或缩小或翻转.在对图片进行操作时占用的内存可能比图片本身要大一些。 3调用图片操作的后,及时的清空,调用recycle()提醒经行垃圾回收。 4尽可能的将一些静态的对象(尤其是集合对象),放于SQLite数据库中。并且对这些数据的搜索匹配尽可能使用sql语句进行。 5一些连接资源在不使用使应该释放,如数据库连接文件输入输出流等。应该避免在特殊的情况下不释放(如异常或其他情况) 6一些长周期的对像引用了短周期的对象,但是这些短周期的对象可能只在很小的范围内使用。所以在查内存中也应该清除这一隐患。如果你想写一个Java程序,观察某对象什么时候会被垃圾收集的执行绪清除,你必须要用一个reference记住此对象,以便随时观察,但是却因此造成此对象的reference数目一直无法为零,使得对象无法被清除。 https://www.360docs.net/doc/d117564923.html,ng.ref.WeakReference 不过,现在有了Weak Reference之后,这就可以迎刃而解了。如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那

么你应该用Weak Reference来记住此对象,而不是用一般的reference。 A obj=new A(); WeakReference wr=new WeakReference(obj); obj=null; //等待一段时间,obj对象就会被垃圾回收 … if(wr.get()==null){ System.out.println(“obj已经被清除了“); }else{ System.out.println(“obj尚未被清除,其信息是 “+obj.toString()); } … 在此例中,透过get()可以取得此Reference的所指到的对象,如果传出值为null的话,代表此对象已经被清除。 这类的技巧,在设计Optimizer或Debugger这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以影响此对象的垃圾收集。 https://www.360docs.net/doc/d117564923.html,ng.ref.SoftReference Soft Reference虽然和Weak Reference很类似,但是用途却不同。被Soft Reference指到的对象,即使没有任何Direct Reference,也不会被清除。一直要到JVM内存不足时且没有Direct Reference

浅谈c5内存优化(dataidataxdata)

对51 单片机内存的认识,很多人有误解,最常见的是以下两种 ①超过变量128后必须使用compact模式编译 实际的情况是只要内存占用量不超过256.0 就可以用small 模式编译 ②128以上的某些地址为特殊寄存器使用,不能给程序用 与PC 机不同,51 单片机不使用线性编址,特殊寄存器与RAM 使用重复的重复的地址。但访问时采用不同的指令,所以并不会占用RAM 空间。 由于内存比较小,一般要进行内存优化,尽量提高内存的使用效率。 以Keil C 编译器为例,small 模式下未指存储类型的变量默认为data型,即直接寻址,只能访问低128 个字节,但这128 个字节也不是全为我们的程序所用,寄存器R0-R7 必须映射到低RAM,要占去8 个字节,如果使用寄存组切换,占用的更多。 所以可以使用data 区最大为120 字节,超出120 个字节则必须用idata 显式的指定为间接寻址,另外堆栈至少要占用一个字节,所以极限情况下可以定义的变量可占247 个字节。当然,实际应用中堆栈为一个字节肯定是不够用的,但如果嵌套调用层数不深,有十几个字节也够有了。 为了验上面的观点,写了个例子 #define LEN 120 data UCHAR tt1[LEN]; idata UCHAR tt2[127]; void main() { UCHAR i,j; for(i = 0; i < LEN; ++i ) { j = i; tt1[j] = 0x55; } } 可以计算R0-7(8) + tt1(120) + tt2(127) + SP(1) 总共256 个字节 keil 编译的结果如下: Program Size: data=256.0 xdata=0 code=30 creating hex file from ".\Debug\Test"... ".\Debug\Test" - 0 Error(s), 0 Warning(s). (测试环境为XP + Keil C 7.5) 这段代码已经达到了内存分配的极限,再定义任何全局变量或将数组加大,编译都会报错107

内存优化技巧 教你怎样优化内存

内存优化技巧教你怎样优化内存 内存优化有时候还是挺有用的。很多时候大内存并不代表你电脑就可以快了。那么怎么优化内存呢?下面就来介绍几招优化内存的方法,有需要的朋友可以参考一下。 内存优化之双通道法 为电脑配置一套双通道内存,是所有内存倍增方案中最有效率的,因为它是唯一一个能在物理上直接让内存带宽倍增的操作方案。 简单来说,双通道架构是由主板上的两套独立内存控制器组成,当两个控制器分别插有一组内存时,这两组控制器就能很容易地实现彼此间零等待时间。 换用一个更通俗的比喻,那就是两组卡车同时跑在一个同向二车道上,这样到达目的地之后,花费同样时间运送的货物肯定要比之前一辆卡车(单条内存)多一些(理论上为单通道的一倍),而这就是对于双通道内存的最佳诠释。 图1 组建双通道内存 那么组建双通道需要有什么特别注意的地方呢?没有,其实这项技术早在几年前就已经在DIYer中流行起来,现行的主板几乎100%支持双通道架构。而且随着这两年技术的升级,如今的双通道早已不像之前那样,还要专门寻找容量一致、性能相近的第二条内存。 只要你的主板支持所谓“弹性双通道”技术,无论第一内存控制器(一般是两组插槽)插着多少内存,也不管里面的内存容量是否相同,只要在另一内存控制器插槽中(颜色会与第一控制器插槽不同)插入对应容量的内存(比如左侧2GB,那么右侧也要插入2GB),系统便会自动匹配并组成内存双通道,性能不受影响。江海论坛https://www.360docs.net/doc/d117564923.html, 内存优化之系统优化法 除了物理双通道外,注册表也是决定大内存性能的另一个因素,毕竟车轮换了发动机也要给力不是!下面小编就简单列举两项与内存性能有关的注册表项吧。江海论坛 https://www.360docs.net/doc/d117564923.html,

低端android机内存管理优化

大家好,今天我主要来和大家交流下低端android手机内存优化的问题。 一、问题的引出 前天,我在论坛发了一个帖子,想请教大家关于联想A68e内存优化的问题,但是回复者寥寥无几,课件也很少有机油对这方面有较深入的 学习了解。我今天中午,查了有关资料,也用了自己的手机进行了测试,觉得可能对A68e(其实是广大低端Android手机)用户有点帮助,所以特地来分享以下。(说明:本人用的是Sumsumg I9103,我媳妇用的是电信套餐的联想A68e,这几天我没拿到她的手机来测试,所以只能自己的手机进行测试,但是我觉得还是具有一定的参考价值的)。二、ROM和RAM 首先,我先解释一下ROM和RAM的区别。 ROM是Read Only Memory,即只读存储器;RAM是Access Random Memory,即随即读写存储器。 ROM是存储程序和数据的,类别电脑的硬盘,可以存放安装的程序、文件、数据等。而论坛中有开AppEXT2的方法(我没试过),那个只是节省出更多的ROM空间,这样可以使程序运行得更为流畅,但是不能解决“同时运行程序的数量最大值太小”的问题。以A68e为例,如果开一个QQ、音乐播放器,再开个UC浏览器估计机子就崩溃而导致程序退出。 RAM才是程序运行时所占用的物理空间。RAM的价格比ROM贵很多,所以RAM的大小一半程度上决定了机子的价位(另一半就是CPU)。

我的Sumsung是1G RAM,同时开QQ、QQ游戏、QQ音乐、浏览器、微信等七、八个程序也毫无压力。所以RAM太小是影响A68e(包括很多Android手机)用户体验的原因。如果你是个游戏玩家、手机达人,那么这类机子一定不适合你。如果你希望能像有高端机那样的用户体验,我建议你还是多话点银子购买配置高的Android手机。 关于官方宣传256的RAM实际上只有170,那是有一部分被Android系统占用。我的手机1GRAM,实际上也只有724M。 三、Android系统内存管理机制及进程调度机制 下面开始具体的分析了。 首先Android系统是基于Linux 内核开发的开源操作系统,li nux系统的内存管理有其独特的动态存储管理机制。Android采取了一种有别于Linux的进程管理策略,Linux系统在进程活动停止后就结束该进程,而Android把这些进程都保留在内存中,直到系统需要更多内存为止。这些保留在内存中的进程通常情况下不会影响整体系统的运行速度,并且当用户再次激活这些进程时,提升了进程的启动速度。 Android系统这样的设计不仅非常适合移动终端(手机、平板)的需要,而且减少了系统崩溃的可能,确保了系统的稳定性。老想着清理内存的同学完全是因为被塞班或者Windows毒害太深,事实上,经常用Taskiller之类的软件关闭后台所有进程,很容易造成系统的不稳定。很多时候出现问题了,只要重启就能解决的原因也在于此。 广大机油一定会发现,关闭了QQ、微信等程序后,其实并没有完全关闭这些程序。这些程序在后台占用了一定的内存,但是并没有运行时

Android减少内存占用专题

Android减少内存占用专题 Android开发经验:不要动不动就分配内存 2011-03-21 开发Andorid应用的开发者都知道,要尽量减少new关键字的使用,因为在手机上GC释放一次内存是一件恐怖的事情,如果你查看一下调试记录,你会发现GC释放内存时有时会花上几百毫秒的时间。可以想象,如果你开发的是游戏,这时你的FPS会下降到多少。 虽然这个原则大家都知道,我们还是会看到一些开发者会出现类似问题,这又是为什么呢?呵呵,其实这是一些隐式的对象创建在作怪,看看以下代码: 原则1:如果可能,请不要使用可变参数 当外部调用时: 系统会自动创建一个临时的数组对象,类似于: 如果该函数经常被调用,则会极大增加GC的压力。所以,如果可能,请不要使用可变参数。 原则2:如果可能,请用StringBuilder代替字符串的相加 我们来看一段代码: 系统会将这句翻译成为如下格式: 这本身没有什么问题,但如果是如下就有意思了: 这段代码等效于:

这样是不是悲剧,本来StringBuilder被无意义的重复创建了多次,期间还在数字转换到文本时创建了String,所以请直接使用显示的StringBuilder来链接字符串。 原则3:尽量将不变的东东设置为常数,特别是字符串 较有效的办法是,你的代码可以这样来写: 当然,即使这样做了,后续对文本操作(如整数到文本转换)仍然是一件费时费力的或,原因是JAVA中,String 是只读的,任何String的内容操作均隐含了new关键字。作者在实际工作中只好采取了更笨笨的办法,自己实现了一个GString类来替代常用的文本操作,其原理时使用预分配的字节内存,只在需要时才转换为String对象。 Android进阶:性能优化篇 2011-05-11 一、图片载入过多出现OutOfMemoryError异常 在使用Gallery控件时,如果载入的图片过多,过大,就很容易出现OutOfMemoryError异常,就是内存溢出。这是因为Android默认分配的内存只有几M,而载入的图片如果是JPG之类的压缩格式,在内存中展开时会占用大量的空间,也就容易内存溢出。这时可以用下面的方法解决: 二、统一管理位图资源,适时释放资源

相关文档
最新文档