我们的线程每200ms从网络摄像头获取一张图片,从JPG转换成Bitmap放到安卓的imageView里。每个循环BitmapFactory会创建新的内存 garbageCollection( )来不及回收 就造成程序死掉。望网求大神指教! 代码如下:  
public Bitmap LoadBitmapFromNetwork(URL url) {
Bitmap vcBitmap = null; try {
String vcCredential = "admin:admin";
String vcEncode = Base64.encodeToString(
vcCredential.getBytes("UTF-8"), Base64.DEFAULT);
URLConnection vcConn = url.openConnection();
vcConn.setRequestProperty("Authorization",
String.format("Basic %s", vcEncode));
HttpURLConnection vcHttpConn = (HttpURLConnection) vcConn; if (vcHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream vcInStream = vcHttpConn.getInputStream();
vcBitmap = BitmapFactory.decodeStream(vcInStream);
vcInStream.close();
} vcHttpConn.disconnect();
} catch (IOException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} return vcBitmap;
} /**
 * 视频直播
 * 
 * @param image
 */
public class VlinCamLive implements Runnable { private ImageView vcImage; public VlinCamLive(ImageView image) {
vcImage = image;
} public void run() {
try {
URL vcUrl = new URL(getBaseContext().getResources().getString(
R.string.camera_ip)); while (true) {
final Bitmap vcBitmap = LoadBitmapFromNetwork(vcUrl); if (vcBitmap != null) {
vcImage.post(new Runnable() {
public void run() {
vcImage.setImageBitmap(vcBitmap);
}
});
} Thread.sleep(100L);
}
} catch (InterruptedException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (MalformedURLException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
}
}
}

解决方案 »

  1.   

    用过调用 
    bmp.recycle();释放资源
      

  2.   

    在每次 vcImage.setImageBitmap(vcBitmap); 之后,释放上个bitmap ,就是调用 .recycle(); 方法。
      

  3.   

    if (vcHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    InputStream vcInStream = vcHttpConn.getInputStream();
                    vcBitmap = BitmapFactory.decodeStream(vcInStream);
                    vcInStream.close();
                }
    图片过大会出错的,可以优化一下(具体看需求)
     第一张图
     vcImage.setImageBitmap(vcBitmap1);
     第二张图
     vcImage.setImageBitmap(vcBitmap2);
     vcBitmap1.recycle();
    不再显示的图片手动释放,差不多就这个意思
      

  4.   

    vcBitmap = BitmapFactory.decodeStream(vcInStream); 你说的每次创建新的内存是这句话,之所以不回收就是你说的系统来不及回收会导致程序死掉,死掉的原因我猜 log打出来的回事 内存溢出,outofmerry    /**
         * Free the native object associated with this bitmap, and clear the
         * reference to the pixel data. This will not free the pixel data synchronously;
         * it simply allows it to be garbage collected if there are no other references.
         * The bitmap is ed as "dead", meaning it will throw an exception if
         * getPixels() or setPixels() is called, and will draw nothing. This operation
         * cannot be reversed, so it should only be called if you are sure there are no
         * further uses for the bitmap. This is an advanced call, and normally need
         * not be called, since the normal GC process will free up this memory when
         * there are no more references to this bitmap.
         */
        public void recycle() {
            if (!mRecycled) {
                mBuffer = null;
                nativeRecycle(mNativeBitmap);
                mNinePatchChunk = null;
                mRecycled = true;
            }
        }源码中说的比较清楚,你可以调用recycle()函数释放将指针置为null,等待系统GC回收,如果不置null系统GC永远不会回收,只会等程序完全退出才会释放内存。但是recycle也不是随便就能用的,很明确当你确定你不在使用时可以调用此函数进行内存释放,也就是说在你显示过之后你就可以将内存释放了。
    我建议你在    public void run() {             try {                 URL vcUrl = new URL(getBaseContext().getResources().getString(                         R.string.camera_ip));                   while (true) {                     final Bitmap vcBitmap = LoadBitmapFromNetwork(vcUrl);                       if (vcBitmap != null) {                         vcImage.post(new Runnable() {                             public void run() {                                 vcImage.setImageBitmap(vcBitmap);  //在这之后加一句 vcBitmap.recycle();                           }                         });                     }                       Thread.sleep(100L);                 }
      

  5.   

    觉得这样做可能有点太快了,没两百毫秒取一张,那么存放多帧用来播放,也就是不能现实下一张的时候立即释放,可能需要存 1s / 200 ms张图片,你可以用个队列把用过的bitmap存起来,超过这个数的2倍 就释放前一半的内存,比如你需要存 50张,那么就是当bitmap达到一百张的时候清除 0 -49下标的内存其实java中内存释放置为null是不行的,这是系统一半不会立即示范内存,内存还在,只是等待GC的回收
    在C/C++中,new出来的内存 想手动释放就是  classP *p = new classP(); delete p; p=null;java只不过是倒过来 先将p=null delete的操作等待系统调用GC时统一释放java的内存管理实际上只是简化了程序猿的操作,不过呢开销比较大,在python 等面向对象语言中都与自己的内存管理方法,甚至在一些类库中都存在自己的管理方法,让程序猿自己在使用类库时减轻指针异常的压力