Throwing OutOfMemoryError“无法分配带有空闲字节的字节分配,直到OOM为止”
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Throwing OutOfMemoryError“无法分配带有空闲字节的字节分配,直到OOM为止”相关的知识,希望对你有一定的参考价值。
我正在尝试制作游戏应用。我有3个活动(简介,游戏/主要和游戏结束)。该游戏在第一次尝试到第三次尝试时都可以正常运行,但是在第四次尝试重试时(在游戏结束活动中有一个重试按钮将您带回到主要活动),我收到此错误:E / art:抛出OutOfMemoryError“无法分配具有7416608可用字节的27581052字节分配,直到OOM为止”
我已经尝试:1)调整我使用的图像/位图的大小;2)将图像放置在不同的可绘制文件夹中,例如xhdpi,xxxhdpi(以及它们之间的所有...);3)在清单中添加android:hardwareAccelerated="false"
和android:largeHeap="true"
;而且所有这些都给我买了更多的重试机会,但并没有解决问题(8至10次尝试后,应用程序会收到相同的错误消息)。
我也尝试过这些,因为我在此论坛的一些答案中找到了它们:4)在游戏结束或主要活动上实现ComponentCallbacks2 onTrimMemory(https://developer.android.com/topic/performance/memory.html);5)在游戏结束或主要活动中添加类似内容:
@Override
public void onDestroy()
super.onDestroy();
Runtime.getRuntime().gc();
而且这些在我的问题上根本没有改变...
这里是Logcat:
04-26 00:22:39.665 31000-31000/com.example.theflyingdactylgameapp I/Timeline: Timeline: Activity_launch_request time:22242888
04-26 00:22:39.755 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc sticky concurrent mark sweep GC freed 2897(97KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 121MB/128MB, paused 548us total 6.523ms
04-26 00:22:39.775 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 137MB to 128MB
04-26 00:22:39.775 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc partial concurrent mark sweep GC freed 1719(109KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 121MB/128MB, paused 394us total 13.719ms
04-26 00:22:39.795 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 136MB to 128MB
04-26 00:22:39.795 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc concurrent mark sweep GC freed 1089(84KB) AllocSpace objects, 0(0B) LOS objects, 5% free, 120MB/128MB, paused 473us total 21.972ms
04-26 00:22:39.795 31000-31000/com.example.theflyingdactylgameapp I/art: Forcing collection of SoftReferences for 26MB allocation
04-26 00:22:39.815 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 136MB to 128MB
04-26 00:22:39.815 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc concurrent mark sweep GC freed 12(384B) AllocSpace objects, 0(0B) LOS objects, 5% free, 120MB/128MB, paused 386us total 17.719ms
04-26 00:22:39.815 31000-31000/com.example.theflyingdactylgameapp E/art: Throwing OutOfMemoryError "Failed to allocate a 27581052 byte allocation with 7416672 free bytes and 7MB until OOM"
04-26 00:22:39.825 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 136MB to 128MB
04-26 00:22:39.825 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc partial concurrent mark sweep GC freed 6(192B) AllocSpace objects, 0(0B) LOS objects, 5% free, 120MB/128MB, paused 387us total 7.547ms
04-26 00:22:39.845 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 136MB to 128MB
04-26 00:22:39.845 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 5% free, 120MB/128MB, paused 368us total 17.285ms
04-26 00:22:39.845 31000-31000/com.example.theflyingdactylgameapp I/art: Forcing collection of SoftReferences for 26MB allocation
04-26 00:22:39.855 31000-31000/com.example.theflyingdactylgameapp I/art: Clamp target GC heap from 136MB to 128MB
04-26 00:22:39.855 31000-31000/com.example.theflyingdactylgameapp I/art: Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 5% free, 120MB/128MB, paused 551us total 17.798ms
04-26 00:22:39.855 31000-31000/com.example.theflyingdactylgameapp E/art: Throwing OutOfMemoryError "Failed to allocate a 27581052 byte allocation with 7416608 free bytes and 7MB until OOM"
04-26 00:22:39.855 31000-31000/com.example.theflyingdactylgameapp D/skia: --- allocation failed for scaled bitmap
04-26 00:22:39.855 31000-31000/com.example.theflyingdactylgameapp D/AndroidRuntime: Shutting down VM
04-26 00:22:39.865 31000-31000/com.example.theflyingdactylgameapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.theflyingdactylgameapp, PID: 31000
java.lang.OutOfMemoryError: Failed to allocate a 27581052 byte allocation with 7416608 free bytes and 7MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:613)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:446)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:469)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:501)
at com.example.theflyingdactylgameapp.FlyingDactylView.<init>(FlyingDactylView.java:57)
at com.example.theflyingdactylgameapp.MainActivity.onCreate(MainActivity.java:21)
at android.app.Activity.performCreate(Activity.java:6041)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1109)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2283)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
at android.app.ActivityThread.access$800(ActivityThread.java:154)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1308)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5273)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
04-26 00:22:39.875 31000-31000/com.example.theflyingdactylgameapp I/Process: Sending signal. PID: 31000 SIG: 9
这是游戏结束活动:
package com.example.theflyingdactylgameapp;
import ...
public class GameOverActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_over);
int score = (int) getIntent().getExtras().get("POPOINTS");
Button startGameAgain = findViewById(R.id.play_again_btn);
TextView displayScore = findViewById(R.id.displayScore);
TextView displayRecord = findViewById(R.id.displayRecord);
//update record
SharedPreferences settings =getSharedPreferences("RECORD", Context.MODE_PRIVATE);
int record = settings.getInt("RECORD", 0);
String score1;
String record1;
if (score > record)
record = score;
record1 = Integer.toString(record);
score1 = Integer.toString(score);
displayScore.setText(String.format("POPOINTS = %s", score1));
displayRecord.setText(String.format("*NEW RECORD* = %s", record1));
SharedPreferences.Editor editor = settings.edit();
editor.putInt("RECORD", record);
editor.apply();
else
record1 = Integer.toString(record);
score1 = Integer.toString(score);
displayScore.setText(String.format("POPOINTS = %s", score1));
displayRecord.setText(String.format("record = %s", record1));
startGameAgain.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Intent mainIntent = new Intent (GameOverActivity.this, MainActivity.class);
startActivity(mainIntent);
);
这是主要活动:
package com.example.theflyingdactylgameapp;
import...
public class MainActivity extends AppCompatActivity
private FlyingDactylView gameView;
private Handler handler = new Handler();
private final static long Interval = 30;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
gameView = new FlyingDactylView(this);
setContentView(gameView);
Timer timer = new Timer();
timer.schedule(new TimerTask()
@Override
public void run()
handler.post(new Runnable()
@Override
public void run()
gameView.invalidate();
);
, 0, Interval);
这是主要活动使用的视图:
package com.example.theflyingdactylgameapp;
import ...
public class FlyingDactylView extends View
private Bitmap dactyl[] = new Bitmap[2];
private int dactylX = 10;
private int dactylY;
private int dactylSpeed;
private int canvasWidth, canvasHeight;
private int popo0X, popo0Y, popo0Speed = 16;
private int popo2X, popo2Y, popo2Speed = 18;
private int popo1X, popo1Y, popo1Speed = 20;
private Bitmap popo[] = new Bitmap[2];
private int redX, redY, redSpeed = 24;
private int red1X, red1Y, red1Speed = 27;
private Bitmap redBall;
private int score, lifeCounterOfDactyl;
private boolean touch = false;
private Bitmap backgroundImage;
private Paint scorePaint = new Paint();
private Bitmap life[] = new Bitmap[2];
// creating sound
private SoundPool soundPool;
private int sound1, sound2, sound3;
// criando objetos na tela
public FlyingDactylView(Context context)
super(context);
dactyl[0] = BitmapFactory.decodeResource(getResources(), R.drawable.dactyl1);
dactyl[1] = BitmapFactory.decodeResource(getResources(), R.drawable.dactyl2);
backgroundImage = BitmapFactory.decodeResource(getResources(), R.drawable.background);
popo[0] = BitmapFactory.decodeResource(getResources(), R.drawable.popo1);
popo[1] = BitmapFactory.decodeResource(getResources(), R.drawable.popo2);
redBall = BitmapFactory.decodeResource(getResources(), R.drawable.red_ball);
scorePaint.setColor(Color.WHITE);
scorePaint.setTextSize(70);
scorePaint.setTypeface(Typeface.DEFAULT_BOLD);
scorePaint.setAntiAlias(true);
life[0] = BitmapFactory.decodeResource(getResources(), R.drawable.egg);
life[1] = BitmapFactory.decodeResource(getResources(), R.drawable.broken_egg);
dactylY = 550;
score = 0;
lifeCounterOfDactyl = 3;
// creating sound player and placing sounds
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
soundPool = new SoundPool.Builder()
.setMaxStreams(5)
.setAudioAttributes(audioAttributes)
.build();
else
soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
sound1 = soundPool.load(this.getContext(), R.raw.fly, 1);
sound2 = soundPool.load(this.getContext(), R.raw.pick_popo, 1);
sound3 = soundPool.load(this.getContext(), R.raw.red_hit, 1);
// movimentos
@Override
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
canvas.drawBitmap(backgroundImage,0, 0, null);
// movimentos dactyl
int minDactylY = dactyl[0].getHeight();
int maxDactylY = canvasHeight - dactyl[0].getHeight() * 3;
dactylY += dactylSpeed;
if (dactylY < minDactylY)
dactylY = minDactylY;
if (dactylY > maxDactylY)
dactylY = maxDactylY;
dactylSpeed += 2;
if (touch)
canvas.drawBitmap(dactyl[1], dactylX, dactylY, null);
touch = false;
else
canvas.drawBitmap(dactyl[0], dactylX, dactylY, null);
// movimentos popó
popo0X -= popo0Speed;
if (hitPopoChecker(popo0X, popo0Y))
score += 10;
popo0X = -100;
// sound when hit popo0
soundPool.play(sound2, 1, 1,0, 0, 1);
if (popo0X < 0)
popo0X = canvasWidth + 21;
popo0Y = (int) Math.floor(Math.random() * (maxDactylY - minDactylY)) + minDactylY;
canvas.drawBitmap(popo[0], popo0X, popo0Y, null);
// movimentos popó2
popo2X -= popo2Speed;
if (hitPopoChecker(popo2X, popo2Y))
score += 10;
popo2X = -100;
// sound when hit popo2
soundPool.play(sound2, 1, 1,0, 0, 1);
if (popo2X < 0)
popo2X = canvasWidth + 21;
popo2Y = (int) Math.floor(Math.random() * (maxDactylY - minDactylY)) + minDactylY;
canvas.drawBitmap(popo[0], popo2X, popo2Y, null);
// movimentos popó gordo
popo1X -= popo1Speed;
if (hitPopoChecker(popo1X, popo1Y))
score += 20;
popo1X = -100;
// sound when hit popo gordo
soundPool.play(sound2, 1, 1,0, 0, 1);
if (popo1X < 0)
popo1X = canvasWidth + 21;
popo1Y = (int) Math.floor(Math.random() * (maxDactylY - minDactylY)) + minDactylY;
canvas.drawBitmap(popo[1], popo1X, popo1Y, null);
// movimentos Red Ball
redX -= redSpeed;
if (hitPopoChecker(redX, redY))
redX = -100;
lifeCounterOfDactyl--;
// sound when hit red ball 1
soundPool.play(sound3, 1, 1,0, 0, 1);
if (lifeCounterOfDactyl == 0)
Toast.makeText(getContext(), "Game Over", Toast.LENGTH_SHORT).show();
Intent gameOverIntent = new Intent(getContext(), GameOverActivity.class);
// free up resources from sound on Game Over by red ball 1
soundPool.release();
soundPool = null;
gameOverIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
gameOverIntent.putExtra("POPOINTS", score);
getContext().startActivity(gameOverIntent);
if (redX < 0)
redX = canvasWidth + 21;
redY = (int) Math.floor(Math.random() * (maxDactylY - minDactylY)) + minDactylY;
canvas.drawBitmap(redBall, redX, redY, null);
// movimentos Red Ball2
red1X -= red1Speed;
if (hitPopoChecker(red1X, red1Y))
red1X = -100;
lifeCounterOfDactyl--;
// sound when hit red ball 1
soundPool.play(sound3, 1, 1,0, 0, 1);
if (lifeCounterOfDactyl == 0)
Toast.makeText(getContext(), "Game Over", Toast.LENGTH_SHORT).show();
Intent gameOverIntent = new Intent(getContext(), GameOverActivity.class);
// free up resources from sound on Game Over by red ball 2
soundPool.release();
soundPool = null;
gameOverIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
gameOverIntent.putExtra("POPOINTS", score);
getContext().startActivity(gameOverIntent);
if (red1X < 0)
red1X = canvasWidth + 21;
red1Y = (int) Math.floor(Math.random() * (maxDactylY - minDactylY)) + minDactylY;
canvas.drawBitmap(redBall, red1X, red1Y, null);
// Score
canvas.drawText("Popoints: " + score, 20, 60, scorePaint);
// life counter
for (int i=0; i<3; i++)
int x = (int) (700 + life[0].getWidth() * 1.9 * i);
int y = 10;
if (i < lifeCounterOfDactyl)
canvas.drawBitmap(life[0], x, y, null);
else
canvas.drawBitmap(life[1], x, y, null);
public Boolean hitPopoChecker (int x, int y)
if (dactylX < x && x < (dactylX + dactyl[0].getWidth()) && dactylY < y && y < (dactylY + dactyl[0].getHeight()))
return true;
return false;
@Override
public boolean onTouchEvent(MotionEvent event)
if (event.getAction() == MotionEvent.ACTION_DOWN)
touch = true;
// decrease here to make Dactyl goes faster
dactylSpeed = -22;
// sound when tap to fly
soundPool.play(sound1, 1, 1,0, 0, 1);
return true;
非常感谢您提供任何有关尝试解决该问题的建议,谢谢!
当您在MainActivity.onCreate中创建计时器任务时,它将保留对活动的引用。永远不会清除该引用,因为计时器线程永远不会停止,因此用于活动的内存永远不会被回收和重新使用。这称为内存泄漏。
您需要在活动中保留对计时器的引用,并在onDestroy中取消计时器。
以上是关于Throwing OutOfMemoryError“无法分配带有空闲字节的字节分配,直到OOM为止”的主要内容,如果未能解决你的问题,请参考以下文章
(HttpWebResponse)request.GetResponse() throwing 操作已经超时