为什么我的应用程序占用大量内存?

SpoocyCrep

因此,我为学校项目制作了一个使用位图和Surfaceview的游戏应用程序。但是该应用程序本身占用了很多内存!只有当您启动它时,它才能达到60mb的内存,并且播放的次数越多,它就会变得越高(有一点它达到了90mb的内存,而游戏则严重滞后)。

看完Google I / O 2011(https://www.youtube.com/watch?v=_CruQY55HOk)之后,我认为这可能是内存泄漏,因为该应用程序是这样启动的:在此处输入图片说明
在播放2分钟后,它最终像那样:
在此处输入图片说明

该应用程序本身看起来尽可能简单,具有8位图形和不多的颜色: 在此处输入图片说明

我使用的所有图像仅重400kb,所以为什么在地狱中需要那么多的内存呢?我以为可能是声音,但是所有声音加起来只有4.45mb的内存,大约是应用程序占用的1/10。我知道位图需要很多内存,但这太荒谬了!

这是我的onLoad:

public GameView(Context c) {
        // TODO Auto-generated constructor stub
        super(c);
        this.c = c;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        ScoreParticleP = new PointF();
        NewScoreParticleP = new PointF();
        int srcWidth = options.outWidth;
        int srcHeight = options.outHeight;
        // it=blocks.iterator();
        // Decode with inSampleSize
        options.inJustDecodeBounds = false;
        options.inDither = false;
        options.inScaled = false;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        this.setKeepScreenOn(true);
        WindowManager wm = (WindowManager) c
                .getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        this.screenw = display.getWidth();
        this.screenh = display.getHeight();
        this.differencew = (double) screenw / normalw;
        this.differenceh = (double) screenh / normalh;
        try{
            mediaPlayer = MediaPlayer.create(c, R.raw.nyan);
            while(mediaPlayer == null) {
                mediaPlayer = MediaPlayer.create(c, R.raw.nyan);
            }
        mediaPlayer.setLooping(true);
        if(mediaPlayer!=null)
        mediaPlayer.start();
        }
        catch(Exception e){

        }
        try{
        mediaPlayer2 = MediaPlayer.create(c, R.raw.remix);
        while(mediaPlayer2==null){
            mediaPlayer2 = MediaPlayer.create(c, R.raw.remix);
        }
        mediaPlayer2.setLooping(true);
        }
        catch(Exception e){

        }
        try{
        mediaPlayer3 = MediaPlayer.create(c, R.raw.weed);
        while(mediaPlayer3==null){
            mediaPlayer3 = MediaPlayer.create(c, R.raw.weed);
        }
        mediaPlayer3.setLooping(true);
        }
        catch(Exception e){

        }
        SharedPreferences prefs2 = c.getSharedPreferences(
                "Sp.game.spiceinspace", Context.MODE_PRIVATE);
        counter2 = prefs2.getInt("score", 0);
        this.sprite = BitmapFactory.decodeResource(getResources(),
                R.drawable.sprite, options);
        this.sprite = Bitmap.createScaledBitmap(sprite, sprite.getWidth() * 3,
                sprite.getHeight() * 3, false);
        this.heart = BitmapFactory.decodeResource(getResources(),
                R.drawable.heart);
        this.explosionheart=BitmapFactory.decodeResource(getResources(),
                R.drawable.explosionheart);
        this.heart = Bitmap.createScaledBitmap(heart, heart.getWidth() * 3,
                heart.getHeight() * 3, false);
        currentSpeed = new PointF(0, 0);
        currentDirection = new Point(0, 0);
        currentPosition = new Point(350, 350);
        this.background = BitmapFactory.decodeResource(getResources(),
                R.drawable.space);
        this.background2=BitmapFactory.decodeResource(getResources(),
                R.drawable.space2);
        this.electricExplosion = BitmapFactory.decodeResource(getResources(),
                R.drawable.effect_explosion);
        this.normalexplison = BitmapFactory.decodeResource(getResources(),
                R.drawable.effect_explosion2);
        this.background = Bitmap.createScaledBitmap(background,
                background.getWidth() * 5, background.getHeight() * 5, false);
        this.background2 = Bitmap.createScaledBitmap(background2,
                background2.getWidth() * 5, background2.getHeight() * 5, false);
        this.lost = BitmapFactory.decodeResource(getResources(),
                R.drawable.gameover);
        this.lostNew = BitmapFactory.decodeResource(getResources(),
                R.drawable.gameovernew);
        lostNew = FitAllDevices(lostNew);
        lost = FitAllDevices(lost);
        this.alien = BitmapFactory.decodeResource(getResources(),
                R.drawable.mob_alien);
        this.coin = BitmapFactory.decodeResource(getResources(),
                R.drawable.item_coin);
        partic = BitmapFactory.decodeResource(getResources(),
                R.drawable.particle_star);
        fire = BitmapFactory.decodeResource(getResources(),
                R.drawable.particle_fire);
        smoke = BitmapFactory.decodeResource(getResources(),
                R.drawable.particle_smoke);
        partic = Bitmap.createScaledBitmap(partic, partic.getWidth() * 2,
                partic.getHeight() * 2, false);
        fire = Bitmap.createScaledBitmap(fire, fire.getWidth() * 2,
                fire.getHeight() * 2, false);
        smoke = Bitmap.createScaledBitmap(smoke, smoke.getWidth() * 2,
                smoke.getHeight() * 2, false);
        electricExplosion = Bitmap.createScaledBitmap(electricExplosion,
                electricExplosion.getWidth() * 2,
                electricExplosion.getHeight() * 2, false);
        normalexplison = Bitmap.createScaledBitmap(normalexplison,
                normalexplison.getWidth() * 3,
                normalexplison.getHeight() * 3, false);
        this.alien = Bitmap.createScaledBitmap(alien, alien.getWidth() * 3,
                alien.getHeight() * 3, false);
        asteroid = BitmapFactory.decodeResource(getResources(),
                R.drawable.mob_astroid);
        bomb = BitmapFactory.decodeResource(getResources(),
                R.drawable.mob_spacebomb);
        asteroid = Bitmap.createScaledBitmap(asteroid, asteroid.getWidth() * 3,
                asteroid.getHeight() * 3, false);
        bomb = Bitmap.createScaledBitmap(bomb, bomb.getWidth() * 3,
                bomb.getHeight() * 3, false);
        goldasteroid = BitmapFactory.decodeResource(getResources(),
                R.drawable.mob_goldastroid);
        goldasteroid = Bitmap.createScaledBitmap(goldasteroid,
                goldasteroid.getWidth() * 3, goldasteroid.getHeight() * 3,
                false);
        mushroom = BitmapFactory.decodeResource(getResources(),
                R.drawable.item_mushroom);
        mushroom = Bitmap.createScaledBitmap(mushroom, mushroom.getWidth() * 4,
                mushroom.getHeight() * 4, false);
        coin = Bitmap.createScaledBitmap(coin, coin.getWidth() * 2,
                coin.getHeight() * 2, false);
        drug = BitmapFactory
                .decodeResource(getResources(), R.drawable.item_not);
        drug = Bitmap.createScaledBitmap(drug, drug.getWidth() * 4,
                drug.getHeight() * 4, false);
        rocket = BitmapFactory.decodeResource(getResources(),
                R.drawable.item_rocket);
        rocket = Bitmap.createScaledBitmap(rocket, rocket.getWidth() * 4,
                rocket.getHeight() * 4, false);
        electricExplosion = FitAllDevices(electricExplosion);
        alien = FitAllDevices(alien);
        normalexplison = FitAllDevices(normalexplison);
        explosionheart = FitAllDevices(explosionheart);
        mushroom = FitAllDevices(mushroom);
        drug = FitAllDevices(drug);
        rocket = FitAllDevices(rocket);
        bomb = FitAllDevices(bomb);
        asteroid = FitAllDevices(asteroid);
        goldasteroid = FitAllDevices(goldasteroid);
        sprite = FitAllDevices(sprite);
        heart = FitAllDevices(heart);
        player = new Spicy(sprite, heart);
        hit = soundPool.load(c, R.raw.hit, 1);
        pass = soundPool.load(c, R.raw.win, 1);
        //remix = soundPool.load(c, R.raw.remix, 1);
        destroy = soundPool.load(c, R.raw.destroy, 1);
        aliensound = soundPool.load(c, R.raw.alien, 1);
        alienexpload = soundPool.load(c, R.raw.explosion2, 1);
        //particlesound = soundPool.load(c, R.raw.particle, 1);
        bigexplosion=soundPool.load(c, R.raw.explosion, 1);
        gameLoopThread = new GameLoopThread(this);
        this.requestFocus();
        this.setFocusableInTouchMode(true);
        holder = getHolder();
        holder.addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                boolean retry = true;
                gameLoopThread.setRunning(false);
                while (retry) {
                    try {
                        gameLoopThread.join();
                        retry = false;
                    } catch (InterruptedException e) {
                    }
                }
            }

              public void surfaceCreated(SurfaceHolder holder) {     
                  if (gameLoopThread.getState()==Thread.State.TERMINATED) { 
                        gameLoopThread = new GameLoopThread(g);
                  }
                  gameLoopThread.setRunning(true);
                  gameLoopThread.start();
          }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format,
                    int width, int height) {
            }
        });
    }

难道我做错了什么?我的应用只是一小块位图游戏,从一侧传到另一侧,起初它运行缓慢,但是您玩的越多,位图就越多,如果上面有很多位图,我会理解这一数量的内存屏幕,但是当播放器和屏幕上的背景什么都没有时,它需要60mb!

我很乐意通过电子邮件将应用程序发送给任何人,以尝试亲身体验一下它多么简单,却无缘无故地花了多少钱。


编辑:

我提到该应用程序随着时间的推移会花费更多的内存,我了解它与以下事实有关:我创建了新的位图,然后将它们移动然后删除,并且播放的次数越多,创建的位图就越多,但是我尝试最好在之后将其删除并回收以确保它们被垃圾收集器收集。我想知道如何最大程度地减少使用量,同时仍使游戏可玩:

这就是我“产生”生物的方式(生物获得我在onLoad上加载的位图):

private void spawnMob() {
    if (timer2 == 0) {
        int mobtype = randInt(1, 40);
        switch (mobtype) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
            Mob m = new Mob(alien, MobEffect.comeback, 1);
            Point p = new Point(0, 0);
            p.y = randInt(0, screenh - alien.getHeight());
            p.x = screenw + alien.getWidth();
            spawned.put(p, m);
            break;

        case 16:
        case 17:
        case 18:
        case 19:
        case 20:
        case 21:
        case 22:
        case 23:
        case 24:
        case 25:
        case 26:
        case 27:
        case 28:
        case 29:
        case 30:
        case 31:
        case 32:
            Mob m2 = new Mob(asteroid, MobEffect.dissapire, 0);
            Point p2 = new Point(0, 0);
            p2.y = randInt(0, screenh - asteroid.getHeight());
            p2.x = screenw + asteroid.getWidth();
            spawned.put(p2, m2);
            break;
        case 33:
        case 34:
        case 35:
        case 36:
        case 37:
        case 38:
        case 39:
            Mob m3 = new Mob(goldasteroid, MobEffect.dissapire, 1);
            Point p3 = new Point(0, 0);
            p3.y = randInt(0, screenh - goldasteroid.getHeight());
            p3.x = screenw + goldasteroid.getWidth();
            spawned.put(p3, m3);
        case 40:
            if (counter > 3) {
                Mob m4 = new Mob(bomb, MobEffect.expload, 1, 5, false,
                        false);
                Point p4 = new Point(0, 0);
                p4.y = randInt(0, screenh - bomb.getHeight());
                p4.x = screenw + bomb.getWidth();
                spawned.put(p4, m4);
            } else {
                Mob m5 = new Mob(asteroid, MobEffect.dissapire, 0);
                Point p5 = new Point(0, 0);
                p5.y = randInt(0, screenh - asteroid.getHeight());
                p5.x = screenw + asteroid.getWidth();
                spawned.put(p5, m5);
            }
            break;
        }
        if (rocketspeed >= 10) {
            timer2 = randInt(1, 8);
        } else {
            if (bleedoff != 35) {
                if (bleedoff > 1)
                    timer2 = randInt(35 / (int) bleedoff,
                            150 / (int) bleedoff);
                else
                    timer2 = randInt(35, 150);
            } else
                timer2 = randInt(1, 10);
        }
    } else {

        timer2--;

    }
}

在onDraw上,我确保删除了小怪,这样当它们不在屏幕上时,它们不会占用额外的内存:

    Iterator<Map.Entry<Point, Mob>> spawnedEntry = spawned
                .entrySet().iterator();
        while (spawnedEntry.hasNext()) {
            Map.Entry<Point, Mob> entry = spawnedEntry.next();
            if(entry.getValue().destroycomplete||entry.getValue().dissapired){
                spawnedEntry.remove();
            }
            else
            entry.getValue().draw(canvas, entry.getKey());

同样在暴民类上:

if(!MobEffectstarted)
        if(!destroycomplete)
    c.drawBitmap(mob,p.x,p.y, null);
        else
            mob.recycle();

编辑2:

这就是eclipse的存储工具告诉我的:在此处输入图片说明
它绝对是位图。


在此处输入图片说明 在此处输入图片说明

哈里·西尔弗(Harry Silver)

为什么我的应用程序在启动时会占用大量RAM?

您的原始图像文件已压缩。您正在解压缩它们并将完整的位图存储在内存中。(大约rowBytes *高度(以字节为单位);找出位图的大小)。例如,背景缩放到原始大小的五倍。由于图像具有二维,因此内存消耗成倍增加。

范例:大小为500x500的图片;它在行之间分配4个字节(32位模式)。这将导致位图大小为500x4 x 500 = 1MB。

如果将此图像缩放2倍,则分配的内存不是两倍,而是:1000x4 x 1000 = 4MB

我能做什么?

  • 如果不需要Alpha通道,则可能需要减少位图的位深度。Bitmap.Config.RGB_565例如使用解码
  • 通过指定样本大小,不要加载超出所需大小的位图。(有关此内容的更多信息:加载大位图
  • 确保您重复使用尽可能多的位图。
  • 仅在需要时加载位图。您是否同时需要两个背景?
  • 您的背景似乎只是一个渐变;您可以使用LinearGradient类进行绘制,以节省庞大的背景图像。(同样的情况也适用于您的正方形,如果它们不仅是占位符。)

关于代码中的内存泄漏:

  • 确保您不经常创建新生物。将“死”生物保存在单独的列表中,并在需要时将其放回演员列表。仅当您实际上用完“待处理”的小怪时才创建新的。
  • 不要在被调用很多的方法中创建对象。(例如:任何与此相关的draw()方法。)

如果您正在蜂窝前测试,则需要回收所有已分配的位图,否则它们可能不会从本机内存中释放。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

编写多部分内容时,为什么我的应用程序的内存占用量会爆炸

来自分类Dev

为什么此Java程序占用大量内存?

来自分类Dev

我的iPhone应用程序占用了太多内存

来自分类Dev

我的iPhone应用程序占用了太多内存

来自分类Dev

为什么我的Android应用占用太多内存?

来自分类Dev

iPhone应用程序在添加图像并加载到uiwebview中时会占用大量内存

来自分类Dev

为什么我的应用程序会泄漏内存?如何避免内存泄漏?

来自分类Dev

为什么我的Fortran代码用f2py封装会占用大量内存?

来自分类Dev

在Rails应用程序中读取大型csv文件会占用大量内存-减少内存消耗的策略?

来自分类Dev

为什么此功能会占用大量内存?

来自分类Dev

为什么此功能会占用大量内存超时

来自分类Dev

为什么我的应用程序崩溃了?

来自分类Dev

为什么我的Android应用程序在高端设备上使用更多的内存?

来自分类Dev

为什么我的paperjs应用占用大量CPU资源并减慢速度?

来自分类Dev

我的应用程序占用的内存随着时间的推移而不断增加

来自分类Dev

为什么这么多应用程序在不使用任何虚拟内存的情况下分配了难以置信的大量虚拟内存?

来自分类Dev

为什么此应用程序未消耗预期的内存

来自分类Dev

为什么单线程应用程序占用多核并限制cpu使用率

来自分类Dev

为什么我的按钮使我的应用程序崩溃?

来自分类Dev

为什么我的Java应用程序(没有内存泄漏)随着时间的推移变得越来越慢

来自分类Dev

当我仅运行一个应用程序(chrome)时,为什么系统会使用2 GB的内存?

来自分类Dev

为什么我的UIImage占用这么多内存?

来自分类Dev

为什么我的UIImage占用这么多内存?

来自分类Dev

为什么[[UINavigationBar外观] setTranslucent:NO]使我的应用程序崩溃?

来自分类Dev

我的应用程序为什么不拨打电话?

来自分类Dev

为什么我的JavaFX应用程序启动这么慢?

来自分类Dev

为什么我的angular 2应用程序不引导?

来自分类Dev

为什么我的PlayFramework应用程序超时很长?

来自分类Dev

为什么我的Expo应用程序不发送消息?

Related 相关文章

  1. 1

    编写多部分内容时,为什么我的应用程序的内存占用量会爆炸

  2. 2

    为什么此Java程序占用大量内存?

  3. 3

    我的iPhone应用程序占用了太多内存

  4. 4

    我的iPhone应用程序占用了太多内存

  5. 5

    为什么我的Android应用占用太多内存?

  6. 6

    iPhone应用程序在添加图像并加载到uiwebview中时会占用大量内存

  7. 7

    为什么我的应用程序会泄漏内存?如何避免内存泄漏?

  8. 8

    为什么我的Fortran代码用f2py封装会占用大量内存?

  9. 9

    在Rails应用程序中读取大型csv文件会占用大量内存-减少内存消耗的策略?

  10. 10

    为什么此功能会占用大量内存?

  11. 11

    为什么此功能会占用大量内存超时

  12. 12

    为什么我的应用程序崩溃了?

  13. 13

    为什么我的Android应用程序在高端设备上使用更多的内存?

  14. 14

    为什么我的paperjs应用占用大量CPU资源并减慢速度?

  15. 15

    我的应用程序占用的内存随着时间的推移而不断增加

  16. 16

    为什么这么多应用程序在不使用任何虚拟内存的情况下分配了难以置信的大量虚拟内存?

  17. 17

    为什么此应用程序未消耗预期的内存

  18. 18

    为什么单线程应用程序占用多核并限制cpu使用率

  19. 19

    为什么我的按钮使我的应用程序崩溃?

  20. 20

    为什么我的Java应用程序(没有内存泄漏)随着时间的推移变得越来越慢

  21. 21

    当我仅运行一个应用程序(chrome)时,为什么系统会使用2 GB的内存?

  22. 22

    为什么我的UIImage占用这么多内存?

  23. 23

    为什么我的UIImage占用这么多内存?

  24. 24

    为什么[[UINavigationBar外观] setTranslucent:NO]使我的应用程序崩溃?

  25. 25

    我的应用程序为什么不拨打电话?

  26. 26

    为什么我的JavaFX应用程序启动这么慢?

  27. 27

    为什么我的angular 2应用程序不引导?

  28. 28

    为什么我的PlayFramework应用程序超时很长?

  29. 29

    为什么我的Expo应用程序不发送消息?

热门标签

归档