细节

全局变量存放在静态存储区


1函数形式参数。在调用函数时给形参分配存储空间。2函数中的


自动变量(未加static声明的局部变量,详见后面的介绍)。3函数调


用时的现场保护和返回地址等。放在动态存储区


000000000000000000000000000000000000000000000000000000000000000000

    栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。

000000000000000000000000000000000000000000000000000000000000000000

[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[

先看一下内存中的供用户使用的存储空间的情况。这个存储空间可以分为三部分,即:

  • 1程序区
  • 2静态存储区:在程序运行期间,系统对变量分配固定的存储空间
  • 3动态存储区:在程序运行期间,系统对变量动态地分配存储空间。
2:全局变量

3:

  • 函数形式参数。在调用函数时给形参分配存储空间。
  • 函数中的自动变量(未加static声明的局部变量,详见后面的介绍)。
  • 函数调用时的现场保护和返回地址等。


]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

------------------------------------------------------------------

存储类别指的是数据在内存中存储的方法。存储方法分为静态存储和动态存储两大类。具体包含4种:自动的(auto)静态的(static)寄存器的(register)外部的(extern)。根据变量的存储类别,可以知道变量的作用域和存储期

int f(int a) //定义f函数,a为形参
{
    auto int b, c=3; //定义b和c为整型的自动变量
}

#include <iostream>
using namespace std;
int f(int a)  //定义f函数,a为形参
{
   auto int  b=0; //定义b为自动变量
   static int c=3; //定义c为静态局部变量
   b=b+1;
   c=c+1;
   return a+b+c;
}

int main( )
{
   int a=2,i;
   for(i=0;i<3;i++)
   cout<<f(a)<<" ";
   cout<<endl;
   return 0;
}

------------------------------------------------------------------

++++++++++++++++++++++++++++++++++++++

不要误认为用static声明的外部变量才采用静态存储方式(存放在静态存储区中),而不加static的是动态存储(存放在动态存储区)。实际上,两种形式的外部变量都用静态存储方式,只是作用范围不同而已,都是在编译时分配内存的。

++++++++++++++++++++++++++++++++++++++


1,异步下载、本地缓存

Android应用中UI线程5秒没响应的话就会抛出无响应异常

{

通信的同步(Synchronous):指向客户端发送请求后,必须要在服务端有回应后客户端才继续发送其它的请求,所以这时所有请求将会在服务端得到同步,直到服务端返回请求。

  通信的异步(Asynchronous):指客户端在发送请求后,不必等待服务端的回应就可以发送下一个请求。



}

android的消息处理有三个核心类:looper,handler和message。其实还有一Message Queue(消息队列),但是MQ被封装到Looper里面了,我们不会直接与MQ打交道,所以它不算是个核心类。

00000000000000000000000000000000000000000000000000000000000

1,消息类------------------message类

2,消息通道---------------looper(通道--循环者)

在一个Activity中,系统会自动帮用户启动Looper对象

而在一个用户自定义的类中,则需要用户手工调用Looper类中的方法,然后才可以正常启动Looper对象。

looper用来使一个普通线程变成Looper线程

public class LooperThread extends Thread{

public void run(){

// 将当前线程初始化为Looper线程

Looper.prepare();

// ...其他处理,如实例化handler

// 开始循环处理消息队列

Looper.loop();

}

}

============================================================

线程本地存储TLS(Thread Local Storage)的原理和实现——分类和原理


我们知道在一个进程中,所有线程是共享同一个地址空间的。

所以,如果一个变量是全局的或者是静态的,那么所有线程访问的是同一份,如果某一个线程对其进行了修改,也就会影响到其他所有的线程。

不过我们可能并不希望这样,所以更多的推荐用基于堆栈的自动变量或函数参数来访问数据,因为基于堆栈的变量总是和特定的线程相联系的。

=============================================================

一个Thread只能有一个Looper对象

public class Looper{

// 每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储(TLS)对象

// ThreadLocal创建一个线程本地变量

private static final ThreadLocal sThreadLocal = new ThreadLocal();    

// Looper内的消息队列    

final MessageQueue mQueue;    

// 当前线程    

Thread mThread;    

//其他属性    

// 每个Looper对象中有它的消息队列,和它所属的线程    

private Looper() 

{        

mQueue = new MessageQueue();        

mRun = true;        

mThread = Thread.currentThread();    

}    

// 我们调用该方法会在调用线程的TLS中创建Looper对象    

public static final void prepare()

 {       

 if (sThreadLocal.get() != null)

 {           

 // 试图在有Looper的线程中再次创建Looper将抛出异常           

 throw new RuntimeException("Only one Looper may be created per thread");   

}       

 sThreadLocal.set(new Looper());    

}    // 其他方法

}

00000000000000000000000000000000000000000000000000000000000

在android中提供两种方法来做这件事

  1. 1,启动一个新的线程来获取资源,完成后通过Handler机制发送消息,并在UI线程中处理消息,从而达到在异步线程中获取图片,然后通过Handler Message来更新UI线程的过程。,

  2. 2,使用android中提供的AsyncTask来完成。

 

具体的做法这里就不介绍了,查下API就可以了,或者是google、baidu下。这里主要来说本地缓存。

1,保存图片到SD卡上

  1. private void saveBmpToSd(Bitmap bm, Stringurl) {  
  2.         if (bm == null) {  
  3.             Log.w(TAG, " trying to savenull bitmap");  
  4.             return;  
  5.         }  
  6.          //判断sdcard上的空间  
  7.         if (FREE_SD_SPACE_NEEDED_TO_CACHE >freeSpaceOnSd()) {  
  8.             Log.w(TAG, "Low free space onsd, do not cache");  
  9.             return;  
  10.         }  
  11.         String filename =convertUrlToFileName(url);  
  12.         String dir = getDirectory(filename);  
  13.         File file = new File(dir +"/" + filename);  
  14.         try {  
  15.             file.createNewFile();  
  16.             OutputStream outStream = newFileOutputStream(file);  
  17.            bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);  
  18.             outStream.flush();  
  19.             outStream.close();  
  20.             Log.i(TAG, "Image saved tosd");  
  21.         } catch (FileNotFoundException e) {  
  22.             Log.w(TAG,"FileNotFoundException");  
  23.         } catch (IOException e) {  
  24.             Log.w(TAG,"IOException");  
  25.         }  
  26.     }  
2,计算sdcard上的空间

  1. /** 
  2.  * 计算sdcard上的剩余空间 
  3.  * @return 
  4.  */  
  5. private int freeSpaceOnSd() {  
  6.     StatFs stat = newStatFs(Environment.getExternalStorageDirectory() .getPath());  
  7.     double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;  
  8.     return (int) sdFreeMB;  
  9. }  
4,修改文件的最后修改时间

  1. /** 
  2.  * 修改文件的最后修改时间 
  3.  * @param dir 
  4.  * @param fileName 
  5.  */  
  6. private void updateFileTime(String dir,String fileName) {  
  7.     File file = new File(dir,fileName);         
  8.     long newModifiedTime =System.currentTimeMillis();  
  9.     file.setLastModified(newModifiedTime);  
  10. }  
5,本地缓存优化

  1. /** 
  2.  *计算存储目录下的文件大小,当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定 
  3.  * 那么删除40%最近没有被使用的文件 
  4.  * @param dirPath 
  5.  * @param filename 
  6.  */  
  7. private void removeCache(String dirPath) {  
  8.     File dir = new File(dirPath);  
  9.     File[] files = dir.listFiles();  
  10.     if (files == null) {  
  11.         return;  
  12.     }  
  13.     int dirSize = 0;  
  14.     for (int i = 0; i < files.length;i++) {  
  15.         if(files[i].getName().contains(WHOLESALE_CONV)) {  
  16.             dirSize += files[i].length();  
  17.         }  
  18.     }  
  19.     if (dirSize > CACHE_SIZE * MB ||FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {  
  20.         int removeFactor = (int) ((0.4 *files.length) + 1);  
  21.   
  22.         Arrays.sort(files, newFileLastModifSort());  
  23.   
  24.         Log.i(TAG, "Clear some expiredcache files ");  
  25.   
  26.         for (int i = 0; i <removeFactor; i++) {  
  27.   
  28.             if(files[i].getName().contains(WHOLESALE_CONV)) {  
  29.   
  30.                 files[i].delete();               
  31.   
  32.             }  
  33.   
  34.         }  
  35.   
  36.     }  
  37.   
  38. }  
  39. /** 
  40.  * 删除过期文件 
  41.  * @param dirPath 
  42.  * @param filename 
  43.  */  
  44. private void removeExpiredCache(StringdirPath, String filename) {  
  45.   
  46.     File file = new File(dirPath,filename);  
  47.   
  48.     if (System.currentTimeMillis() -file.lastModified() > mTimeDiff) {  
  49.   
  50.         Log.i(TAG, "Clear some expiredcache files ");  
  51.   
  52.         file.delete();  
  53.   
  54.     }  
  55.   
  56. }  
内存保存:

{{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}{}}

在内存中保存的话,只能保存一定的量,而不能一直往里面放,需要设置数据的过期时间、LRU等算法。这里有一个方法是把常用的数据放到一个缓存中(A),不常用的放到另外一个缓存中(B)。当要获取数据时先从A中去获取,如果A中不存在那么再去B中获取。B中的数据主要是A中LRU出来的数据,这里的内存回收主要针对B内存,从而保持A中的数据可以有效的被命中。

1,先定义A缓存

  1. private final HashMap<String, Bitmap>mHardBitmapCache = new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY/ 20.75f, true) {  
  2.         @Override  
  3.         protected booleanremoveEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {  
  4.             if (size() >HARD_CACHE_CAPACITY) {  
  5.                //当map的size大于30时,把最近不常用的key放到mSoftBitmapCache中,从而保证mHardBitmapCache的效率  
  6.                mSoftBitmapCache.put(eldest.getKey(), newSoftReference<Bitmap>(eldest.getValue()));  
  7.                 return true;  
  8.             } else  
  9.                 return false;  
  10.         }  
  11.     };  
2,再定义B缓存

  1. /** 
  2.   *当mHardBitmapCache的key大于30的时候,会根据LRU算法把最近没有被使用的key放入到这个缓存中。 
  3.   *Bitmap使用了SoftReference,当内存空间不足时,此cache中的bitmap会被垃圾回收掉 
  4.   */  
  5.  private final staticConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache =new ConcurrentHashMap<String,SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);  
3,从缓存中获取数据

  1. /** 
  2.      * 从缓存中获取图片 
  3.      */  
  4.     private Bitmap getBitmapFromCache(Stringurl) {  
  5.         // 先从mHardBitmapCache缓存中获取  
  6.         synchronized (mHardBitmapCache) {  
  7.             final Bitmap bitmap =mHardBitmapCache.get(url);  
  8.             if (bitmap != null) {  
  9.                 //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除  
  10.                 mHardBitmapCache.remove(url);  
  11.                 mHardBitmapCache.put(url,bitmap);  
  12.                 return bitmap;  
  13.             }  
  14.         }  
  15.         //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找  
  16.         SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);  
  17.         if (bitmapReference != null) {  
  18.             final Bitmap bitmap =bitmapReference.get();  
  19.             if (bitmap != null) {  
  20.                 return bitmap;  
  21.             } else {  
  22.                 mSoftBitmapCache.remove(url);  
  23.             }  
  24.         }  
  25.         return null;  
  26.     }  


=========================================================================================================================================================================================================================================================================================================================================================


1,所有的进程都需要分配内存,对c/c++来说,分配和管理内存是已经很有挑战性的工作,nedmalloc是一个跨平台的高性能多线程内存分配库。

2,缓存库用的最多的就是memcache了。在做数据库开发时特别有用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值