当前位置: 动力学知识库 > 问答 > 编程问答 >

java - Leak of memory and optimization

问题描述:

I'm currently developing an Android application and I can't end it because of few issue as "Out of Memory", I think there is two part in my code which could cause leak.

  • First : The application has to play like 12 tones at the same time (10 different frequencies). I found a piece of code on Stack Overflow which allow me to play a list of frequencies at the same time : (I think this is cause by AudioTrack but I don't know how to solve it)

    public static void runList(final List<Double> freq) {

    if(audioTrack!=null){

    audioTrack.release();

    audioTrack=null;

    }

    final List<AudioTrack> audioTrackList = new ArrayList();

    final AudioTrack audioTrack0;

    final AudioTrack audioTrack1;

    genTone(freq.get(0));

    audioTrack0 = new AudioTrack(AudioManager.STREAM_MUSIC,

    (int) sampleRate, AudioFormat.CHANNEL_OUT_DEFAULT,AudioFormat.ENCODING_PCM_16BIT,

    generatedSnd.length, AudioTrack.MODE_STREAM);

    audioTrack0.play();

    audioTrack0.write(generatedSnd, 0, generatedSnd.length);

    genTone(freq.get(1));

    audioTrack1 = new AudioTrack(AudioManager.STREAM_MUSIC,

    (int) sampleRate, AudioFormat.CHANNEL_OUT_DEFAULT,AudioFormat.ENCODING_PCM_16BIT,

    generatedSnd.length, AudioTrack.MODE_STREAM);

    audioTrack1.play();

    audioTrack1.write(generatedSnd, 0, generatedSnd.length);

    handler.postDelayed(new Runnable() {

    @Override

    public void run() {

    //compteur : not more than 2 AudioTrack

    audioTrack0.release();

    audioTrack1.release();

    }

    }, 1000);

    }

(With this I can only play 2 tones at the same time)

  • Then : In the same activity the application has to display on the screen 10 image View, each one is moving with a different way. All these image View have been previously decoded from Bitmap. I think that the leak come from here. I've tried to release Bitmap after using it, but nothing to do, I can only display like 3 or 4 image moving on the screen before a crash (Out of Memory). There is maybe a better and lighter way to anim image, for example, to animate an image and make it follow a triangle way, I use this :

    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

    }

    }); }

  • Finally, is there any software or code or anything else that could help me to find where my application has leak of memory ? I can link you errors from LogCat if needed.

Sorry for my english, hope there is not much mistakes.

UPDATE :

Here is my logcat :

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)

To decode Bitmaps I use this :

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;

}

网友答案:

Just one quick thought: Make sure to close your InputStream(s), BitmapFactory.decodeStream(); doesn't seem to do this in the source code

分享给朋友:
您可能感兴趣的文章:
随机阅读: