Java 内存泄漏与优化

Java 内存泄漏与优化,java,android,memory-leaks,bitmap,Java,Android,Memory Leaks,Bitmap,我目前正在开发一个Android应用程序,我不能结束它,因为“内存不足”这类问题很少,我认为我的代码中有两部分可能导致泄漏 第一:应用程序必须同时播放12个音调(10个不同频率)。我在堆栈溢出上发现了一段代码,允许我同时播放一系列频率:(我认为这是由AudioTrack引起的,但我不知道如何解决) 要解码位图,我使用以下方法: private Bitmap decodeFile(File f){ try { //decode image size Bit

我目前正在开发一个Android应用程序,我不能结束它,因为“内存不足”这类问题很少,我认为我的代码中有两部分可能导致泄漏

  • 第一:应用程序必须同时播放12个音调(10个不同频率)。我在堆栈溢出上发现了一段代码,允许我同时播放一系列频率:(我认为这是由AudioTrack引起的,但我不知道如何解决)

    要解码位图,我使用以下方法:

    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);              
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale++;
            }
    
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    
    }
    
    私有位图解码文件(文件f){
    试一试{
    //解码图像大小
    BitmapFactory.Options o=新的BitmapFactory.Options();
    o、 inJustDecodeBounds=true;
    解码流(新的FileInputStream(f),null,o);
    //找到正确的刻度值。它应该是2的幂。
    所需的最终int_尺寸=70;
    内部宽度=o.向外宽度,高度=o.向外高度;
    int标度=1;
    while(true){
    
    如果(width_tmp/2只是一个简单的想法:确保关闭InputStream,
    BitmapFactory.decodeStream()
    在源代码中似乎没有这样做

    把你的日志放在它说它泄露了内存的地方10个位图,这是一个很小的内存,你是如何解码的?把你的代码贴出来,给我贴上标签谢谢。这是logcat OutofMemory由ImageView引起的。你能记录下刻度,看看总是返回的数字是多少吗?既然你只需要一个具有固定大小的位图我想你不需要循环缩放它。只需给出一个固定的inSampleSize=4或更高。或者只使用scaleBitmap,但这会降低质量,但我认为它不会那么明显,因为图像大小会很小。
    private void triangleAnim(final ImageView patternImage, final int bpm, final int i, final double frequency) {
    
    resetN();
    int randomLeft = (int)(Math.random() * (maxRandomLeft-minRandomLeft)) + minRandomLeft;
    int randomTop = (int)(Math.random() * (maxRandomTop-minRandomTop)) + minRandomTop;
    
    final Animation anim = new TranslateAnimation(randomLeft, randomLeft + 300,randomTop,randomTop + 300 ); 
    anim.setDuration(60000/bpm);
    final Animation anim2 = new TranslateAnimation(randomLeft +300, randomLeft-300, randomTop+300, randomTop+300 );
    anim2.setDuration(60000/bpm);
    final Animation anim3 = new TranslateAnimation(randomLeft-300, randomLeft, randomTop+300, randomTop );
    anim3.setDuration(60000/bpm);
    su = new SoundUtils();
    su.setDuration(60000/bpm);
    patternImage.startAnimation(anim);
    
    anim.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationEnd(Animation animation) {
            patternImage.startAnimation(anim2);
            ;
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    
        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
        }
    });
    
    anim2.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationEnd(Animation animation) {
            patternImage.startAnimation(anim3);
            ;
            incrementN();
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {    
        }
    
        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub      
        }
    });
    
    anim3.setAnimationListener(new Animation.AnimationListener() {
        @Override
        public void onAnimationEnd(Animation animation) {                           
            if(n <= i){
                patternImage.startAnimation(anim);
    
            }
        }
    
        @Override
        public void onAnimationRepeat(Animation animation) {
        }
    
        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
        }
    });  }
    
    07-31 17:54:03.931: E/AndroidRuntime(15181): java.lang.OutOfMemoryError
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at      android.graphics.Bitmap.nativeCreate(Native Method)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.graphics.Bitmap.createBitmap(Bitmap.java:903)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.graphics.Bitmap.createBitmap(Bitmap.java:880)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.graphics.Bitmap.createBitmap(Bitmap.java:847)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.CameraBridgeViewBase.AllocateCache(CameraBridgeViewBase.java:451)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.JavaCameraView.initializeCamera(JavaCameraView.java:184)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.JavaCameraView.connectCamera(JavaCameraView.java:239)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.CameraBridgeViewBase.onEnterStartedState(CameraBridgeViewBase.java:355)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.CameraBridgeViewBase.processEnterState(CameraBridgeViewBase.java:318)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.CameraBridgeViewBase.checkCurrentState(CameraBridgeViewBase.java:311)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.CameraBridgeViewBase.enableView(CameraBridgeViewBase.java:228)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at ui.fragment.TakePictureFragment$1.onManagerConnected(TakePictureFragment.java:71)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at org.opencv.android.AsyncServiceHelper$1.onServiceConnected(AsyncServiceHelper.java:318)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1119)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1136)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.os.Handler.handleCallback(Handler.java:733)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.os.Handler.dispatchMessage(Handler.java:95)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.os.Looper.loop(Looper.java:157)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at android.app.ActivityThread.main(ActivityThread.java:5356)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at java.lang.reflect.Method.invokeNative(Native Method)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at java.lang.reflect.Method.invoke(Method.java:515)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
    07-31 17:54:03.931: E/AndroidRuntime(15181):    at dalvik.system.NativeStart.main(Native Method)
    
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);              
            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale++;
            }
    
            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    
    }