我正在制作Android应用程序,我正在尝试从TextureView中获取的位图图像生成视频。在这里,我能够从TextureView获取位图图像,并能够将其保存在内部存储中,以便以后生成视频。但问题是,当位图图像被创建并保存在本地存储中时,App的堆大小也在快速增长,之后将大约800个图像保存为.png文件后,它会将Clamp目标GC堆的OutOfMemory异常从258MB提高到256MB。那么,我如何避免堆积增长?
我尝试增加app堆大小,但随着堆的增长,随着新图像的创建和保存,它没有用。我尝试了位图回收并将null设置为位图,但性能没有变化。
//从textureview获取位图的代码
Bitmap bitmap = textureView.getBitmap(TF_OD_API_INPUT_SIZE, TF_OD_API_INPUT_SIZE);
//屏幕上显示的位图
if(croppedBitmap!=null){
croppedBitmap=null;
}
croppedBitmap = Bitmap.createBitmap((int) canvasWidth, (int) canvasHeight, Bitmap.Config.ARGB_8888);
上面的代码定期运行并使用Runnable#run()调用
当用户按下记录按钮时,代码执行并且当纹理表面得到更新,并在本地保存为位图
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
if(Utils.isVideoRecordingStarted(activity)){
//if it already has bitmap recycle it to create room
if(mToVideo!=null){
mToVideo.recycle();
mToVideo=null;
}
if(newImage!=null){
newImage.recycle();
newImage=null;
}
//hold bitmap image
mToVideo = textureView.getBitmap(VideoManagerConfig.VIDEO_WIDTH,VideoManagerConfig.VIDEO_HEIGHT);
if(mToVideo!=null) {
if(activity.getResources().getConfiguration().orientation!=ORIENTATION_PORTRAIT){
mToVideo = textureView.getBitmap(VideoManagerConfig.VIDEO_HEIGHT,VideoManagerConfig.VIDEO_WIDTH);
if(mToVideo!=null){
newImage = Utils.RotateBitmap(mToVideo.copy(mToVideo.getConfig(),true),90);
Log.i(ObjectDetectionCameraImpl.TAG,"W: "+newImage.getWidth()+", H: "+newImage.getHeight());
SaveToLocalStorage(newImage);
}
}else {
SaveToLocalStorage(mToVideo.copy(mToVideo.getConfig(),true));
}
mToVideo=null;
}
}else if(isInitilizedVideo && !Utils.isVideoRecordingStarted(activity)){
//video stopped and has something to encode
imageFromTextureListener.getBuffer(getBufferMetaData());
}
}
};
以下是保存图像时生成的日志。
VideoManager:images_924.png //表示925图像已经保存在本地索引从0开始
缓冲区:925/1800 //这里1800 =>将保存的总图像
Following the link to log file:
https://drive.google.com/open?id=1GxFV-h2V68FSoWRs9K1AYhZChnlTFFqq
尝试缩放图像时发生的类似问题(在java中)回答here如下:除非发生垃圾收集,否则JVM(android使用ART)会在需要时继续扩展堆,一直到给它的完整堆大小。简而言之,
Java进程可以自由使用您提供的所有内存。