java - 内存不足错误 - 可能是由于内存泄漏?

标签 java android memory memory-leaks out-of-memory

所以我在使用 android 模拟器时遇到了代码问题。我得到同样的错误:Throwing OutOfMemoryError“无法分配 4776816 字节的分配,其中有 2473998 个可用字节和 2MB,直到 OOM” 我有一种感觉,这是由于内存泄漏,因为我在每个其他类中为每个类创建对象,我想它会导致某种循环错误。这在Java中是不允许的吗?任何帮助将不胜感激..

代码如下:

public class BoardActivity extends AppCompatActivity {

Move move = new Move();
Button buttons[] = new Button[16];

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_board);

    move.newGame();


    buttons[0] = (Button)findViewById(R.id.button1);buttons[0].setOnClickListener(new Button.OnClickListener(){
        public void onClick(View v){
           move.makeMove(move.cups.get(0));
            updateButtons();
        }});
    buttons[1] = (Button)findViewById(R.id.button2);buttons[1].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(1));
            updateButtons();
        }
    });
    buttons[2] = (Button)findViewById(R.id.button3);buttons[2].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(2));
            updateButtons();
        }
    });
    buttons[3] = (Button)findViewById(R.id.button4);buttons[3].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(3));
            updateButtons();
        }
    });
    buttons[4] = (Button)findViewById(R.id.button5);buttons[4].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(4));
            updateButtons();
        }
    });
    buttons[5] = (Button)findViewById(R.id.button6);buttons[5].setOnClickListener(new Button.OnClickListener(){
        public void onClick(View v){
            move.makeMove(move.cups.get(5));
            updateButtons();
        }
    });
    buttons[6] = (Button)findViewById(R.id.button7);buttons[6].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(6));
            updateButtons();
        }
    });
    buttons[7] = (Button)findViewById(R.id.button8);buttons[7].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            updateButtons();
        }
    });
    buttons[8] = (Button)findViewById(R.id.button9);buttons[8].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(8));
            updateButtons();
        }
    });
    buttons[9] = (Button)findViewById(R.id.button10);buttons[9].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(9));
            updateButtons();
        }
    });
    buttons[10] = (Button)findViewById(R.id.button11);buttons[10].setOnClickListener(new Button.OnClickListener(){
        public void onClick(View v){
            move.makeMove(move.cups.get(10));
            updateButtons();
        }
    });
    buttons[11] = (Button)findViewById(R.id.button12);buttons[11].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(11));
            updateButtons();
        }
    });
    buttons[12] = (Button)findViewById(R.id.button13);buttons[12].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
             move.makeMove(move.cups.get(12));
            updateButtons();
        }
    });
    buttons[13] = (Button)findViewById(R.id.button14);buttons[13].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(13));
            updateButtons();
        }
    });
    buttons[14] = (Button)findViewById(R.id.button15);buttons[14].setOnClickListener(new Button.OnClickListener() {
        public void onClick(View v) {
            move.makeMove(move.cups.get(14));
            updateButtons();
        }
    });
    // Still have bug with this button - needs to be sorted
    buttons[15] = (Button)findViewById(R.id.button16);buttons[15].setOnClickListener(new Button.OnClickListener(){
        public void onClick(View v){
            updateButtons();
        }
    });

    updateButtons();
}


public void updateButtons(){
    for(int i=0; i<buttons.length; i++){
        buttons[i].setText(move.cups.get(i).toString());
    }
}
}

玩家类:

public class Player extends Move{

Random rand = new Random();
BoardActivity board = new BoardActivity();

/**public void setScoreCups(){
    if(returnCurrentPlayer()==1){
        oppositionScoreCup = cups.get(16);
        scoreCup = cups.get(8);
    }else{
        oppositionScoreCup = cups.get(8);
        scoreCup = cups.get(16);
    }
}**/
public void setNextPlayer(){
    if(returnCurrentPlayer()==1) {
        setTurnPlayer(2);
    }else if(returnCurrentPlayer()==2){
        setTurnPlayer(1);
    }
}
public int returnCurrentPlayer(){
    if(board.buttons[5].isEnabled()){
        return 1;
    }else{
        return 2;
    }
}
public void setRandomPlayer(){
    boolean b = rand.nextBoolean();
    if(b){
        setTurnPlayer(1);
    }else{
        setTurnPlayer(2);
    }
}

public void setTurnPlayer(int n){
    if(n==1) {
        for (int i = 1; i < 8; i++) {
            board.buttons[i].setEnabled(true);
        }
        for (int i = 9; i < 16; i++) {
            board.buttons[i].setEnabled(false);
        }
    }else if(n==2){
        for(int i=1; i<8; i++){
            board.buttons[i].setEnabled(false);
        }
        for(int i=9; i<16; i++){
            board.buttons[i].setEnabled(true);
        }
    }
}
public void setPlayer() {
    if ((move.currentCup.pebbleCount == 0) && (move.currentCup != move.scoreCup)) {
        Log.d("makeMove.java", "print cup index" + move.cups.indexOf(move.currentCup));
        //emptyCupSwitch(currentCup);
        move.currentCup.increasePebbleCount();
    }
    if (move.currentCup == move.scoreCup) {
        move.currentCup.increasePebbleCount();
        setTurnPlayer(move.currentPlayer);
    } else if (move.currentCup != move.scoreCup) {
        move.currentCup.increasePebbleCount();
        setNextPlayer();
    }
}


//needs to be changed



public static int score=0;

public void setScore(int n){

    score = n;
}

}

和移动类:

public class Move extends Game{

Player player = new Player();
public Cup oppositionScoreCup; public Cup scoreCup;
int i; int currentPlayer; int cupValue;
int currentIndex; int lastCupIndex = currentIndex + cupValue - 1;
Cup currentCup;

public List<Cup> cups;
public void newGame() {

    cups = new ArrayList<>();
    //Reset all cups
    for (int i = 0; i < 16; i++) {
        Cup cup = new Cup(7);
        cups.add(i, cup);
    }
}

//Returns the cup following the one entered in the parameters
public Cup getNextCup(Cup cup) {
    if (cups.indexOf(cup) == 15) {
        return cups.get(0);
    } else {
        return cups.get(cups.indexOf(cup) + 1);
    }
}


//Emptys current cup and switches pebbles to opposite side
public void emptyCupSwitch(Cup cup) {
    Cup oppCup;
    int index = cups.indexOf(cup);
    switch(index) {
        case 1:
            oppCup = cups.get(15);
            cups.get(1).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
            break;
        case 2:
            oppCup = cups.get(14);
            cups.get(2).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
            break;
        case 3:
            oppCup = cups.get(13);
            cups.get(3).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
            break;
        case 4:
            oppCup = cups.get(12);
            cups.get(4).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 5:
            oppCup = cups.get(11);
            cups.get(5).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 6:
            oppCup = cups.get(10);
            cups.get(6).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 7:
            oppCup = cups.get(9);
            cups.get(7).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 9:
            oppCup = cups.get(7);
            cups.get(9).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 10:
            oppCup = cups.get(6);
            cups.get(10).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 11:
            oppCup = cups.get(5);
            cups.get(11).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 12:
            oppCup = cups.get(4);
            cups.get(12).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 13:
            oppCup = cups.get(3);
            cups.get(13).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 14:
            oppCup = cups.get(2);
            cups.get(7).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
        case 15:
            oppCup = cups.get(1);
            cups.get(7).pebbleCount += oppCup.pebbleCount;
            oppCup.emptyCup();
    }


}


//Method for Clicking Cup - Basic move - Skips oppositonScoreCup
public void makeMove(Cup cup) {
    cupValue = cup.returnPebbleCount();
    currentIndex = cups.indexOf(cup);
    currentCup = getNextCup(cup);
    cup.emptyCup();

    for (i = currentIndex; i < currentIndex + cupValue; i++) {

        if (i == lastCupIndex) {
           player.setPlayer();
        } else if (currentCup == oppositionScoreCup) {
            currentCup = getNextCup(currentCup);
        } else if (currentCup != oppositionScoreCup) {
            currentCup.increasePebbleCount();
            currentCup = getNextCup(currentCup);
        }
    }
    if(checkGameOver()){
        gameOver();
    }
}
}

最佳答案

您的内存不足,因为您的代码将递归运行并创建无限数量的 BoardActivityMovePlayer 对象。

如何?那么,当 BoardActivity 类被初始化时,行

Move move = new Move();

将创建新的 Move 对象。这反过来将导致该行的执行

Player player = new Player();

Move 类中。这将生成一个新的 Player 对象,其中包含

BoardActivity board = new BoardActivity();

现在这将创建另一个 BoardActivity 对象,这将我们带回到创建无限对象生成循环的开始。

简单的说,BoardActivity->Move->Player->BoardActivity->Move->播放器....

我猜 AppCompatActivity 是一个 android Activity 。 Android Activity 非常繁重,并且在初始化时会分配大量堆内存。这基本上就是您如此快地耗尽内存的原因。

您不应该以这种方式创建 Activity 。创建一个并从主要 Activity 开始,或者使用 AndroidManifest

将其加载为默认 Activity

此外,与其为每个按钮创建单独的 OnClickListener,不如创建一个 OnClickListener 并使用 if 语句检查按钮 ID 以确定单击了哪个按钮会更好.

关于java - 内存不足错误 - 可能是由于内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33352160/

相关文章:

java - json 模式 validator NoClassDefFoundError : com/google/common/io/Closer

javascript - 如何在 android 上运行我的 node.js 项目?

java - 如何在android中扩展2个库类

performance - 使用 'static vs ' a 有什么性能差异?

java - 必填国家组合框

java - 从工作流步骤查找工作流实例

java - 通过 URL 处理程序在 Eclipse 中打开文件

java - 错误 java.lang.NoSuchMethodError : No static method

c++ - 为什么 CUDA 中的外部共享内存存在未定义的行为?

android - 在 Android 上绘制内存高效的谷歌地图