Не удается найти то, что я считаю утечкой памяти в программе predator prey

#java #arraylist #memory-leaks

#java #arraylist #утечки памяти

Вопрос:

У меня есть шесть классов для моей программы, и я считаю, что большая часть моего кода верна, но когда я запускаю его, никаких инструкций print не происходит, и вместо этого программа продолжает работать вечно без вывода. Это вызывает массовую утечку памяти, если я запускаю симуляцию для больших чисел (100 ). Кажется, я не могу найти, в чем проблема, но код просто не выполняется должным образом.

**** (откуда я запускаю программу и где, как я думаю, ошибка)

 import java.util.*;
public class {
    public static void main(String[]args){
        SubSim simulate=new SubSim();
        ArrayList<Wolf>WolfArrayList=new ArrayList<>();
        ArrayList<Moose>MooseArrayList=new ArrayList<>();
        ArrayList<Grass>GrassArrayList=new ArrayList<>();
        for (int i=0;i<simulate.getInitialWolves();i  ){
            WolfArrayList.add(new Wolf(simulate));
        }
        for (int i=0;i<simulate.getInitialMoose();i  ){
            MooseArrayList.add(new Moose(simulate));
        }
        for (int i=0;i<simulate.getMaxX();i  ){
            for (int j=0;i<simulate.getMaxY();j  ){
                int grassroll=(int)(Math.random()*5);
                if (grassroll==1||grassroll==2||grassroll==3||grassroll==4){
                    GrassArrayList.add(new Grass(simulate,i,j,2));
                }
                else{
                    GrassArrayList.add(new Grass(simulate,i,j,0));
                }
            }
        }
        simulate.setGrassArrayList(GrassArrayList);
        simulate.setMooseArrayList(MooseArrayList);
        simulate.setWolfArrayList(WolfArrayList);
        System.out.println("Ticks        Wolves          Moose");
        for(int i=1;i<=20;i  ){
            System.out.printf("%d           %d          %dn",(i-1),simulate.getWolfPop(),simulate.getMoosePop());
            simulate.run();
        }
    }
}
  

** Класс**

     import java.util.*;
public class  extends Simulator{
//making private variables
private ArrayList<Grass> GrassArrayList;
private ArrayList<Moose> MooseArrayList;
private ArrayList<Wolf> WolfArrayList;
//using the animals move method
@Override
public void animalsMove() {
    for (int i = 0; i < WolfArrayList.size(); i  ) {
        WolfArrayList.get(i).move();
        WolfArrayList.get(i).setEnergy(WolfArrayList.get(i).getEnergy()-getMovementCost());
    }
    for (int i = 0; i < MooseArrayList.size(); i  ) {
        MooseArrayList.get(i).move();
        MooseArrayList.get(i).setEnergy(MooseArrayList.get(i).getEnergy()-getMovementCost());

    }
}
//using the animals die method
@Override
public void animalsDie(){
        int WolfArraySize=WolfArrayList.size();
        for (int i=0;i<WolfArraySize;i  ) {
            if (WolfArrayList.get(i).getEnergy() <= 0){
                WolfArrayList.remove(i);
                WolfArraySize = WolfArrayList.size();
            }
        }
    int MooseArraySize=MooseArrayList.size();
    for (int i=0;i<WolfArraySize;i  ){
        if (MooseArrayList.get(i).getEnergy() <= 0){
            MooseArrayList.remove(i);
            MooseArraySize = MooseArrayList.size();
        }
    }
}
//using animals eat method
@Override
public void animalsEat() {
    for (int i = 0; i < WolfArrayList.size(); i  ) {
        for (int j = 0; j < MooseArrayList.size(); j  ) {
            if (MooseArrayList.get(j).getLocationX() == WolfArrayList.get(i).getLocationX() amp;amp; MooseArrayList.get(j).getLocationY() == WolfArrayList.get(i).getLocationY()) {
                MooseArrayList.remove(j);
                WolfArrayList.get(i).eat();
            }
        }
    }
    for (int i = 0; i < MooseArrayList.size(); i  ) {
        for (int j = 0; j < GrassArrayList.size(); j  ) {
            if (MooseArrayList.get(i).getLocationX() == GrassArrayList.get(j).getXcord() amp;amp; MooseArrayList.get(i).getLocationY() == GrassArrayList.get(j).getYcord()) {
                MooseArrayList.remove(j);
                WolfArrayList.get(i).eat();
            }
        }
    }
}
//using animals reproduce method
@Override
public void animalsReproduce(){
    for (int i=0;i<WolfArrayList.size();i  ){
        if (WolfArrayList.get(i).getEnergy() >= 100) {
            Wolf puppy = (Wolf) WolfArrayList.get(i).reproduce();
            WolfArrayList.add(puppy);
            WolfArrayList.get(i).setEnergy(getInitialEnergy());
        }
    }
    for (int i=0;i<MooseArrayList.size();i  ) {
        if (MooseArrayList.get(i).getEnergy() >= 100) {
            Moose calf = (Moose) MooseArrayList.get(i).reproduce();
            MooseArrayList.add(calf);
            MooseArrayList.get(i).setEnergy(getInitialEnergy());
        }
    }
}
//using grass grows method
@Override
public void grassGrows(){
        for(int i=0;i<GrassArrayList.size();i  ){
            if (GrassArrayList.get(i).getLength()>0){
                GrassArrayList.get(i).setLength((int)(GrassArrayList.get(i).getLength() getGrassGrowthRate()));
            }
            //making shorthand instanced variables
            int xcord=GrassArrayList.get(i).getXcord();
            int ycord=GrassArrayList.get(i).getYcord();
            if(GrassArrayList.get(i).getLength()>=10){
                for (int j=0;j<GrassArrayList.size();j  ){
                    //checking area around tall grass to place seeds
                    if(xcord==GrassArrayList.get(j).getXcord() amp;amp; ycord 1==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() amp;amp; ycord 1==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() amp;amp; ycord==GrassArrayList.get(j).getYcord() || xcord-1==GrassArrayList.get(j).getXcord() amp;amp; ycord-1==GrassArrayList.get(j).getYcord() || xcord==GrassArrayList.get(j).getXcord() amp;amp; ycord-1==GrassArrayList.get(j).getYcord() || xcord 1==GrassArrayList.get(j).getXcord() amp;amp; ycord-1==GrassArrayList.get(j).getYcord() || xcord 1==GrassArrayList.get(j).getXcord() amp;amp; ycord==GrassArrayList.get(j).getYcord() || xcord 1==GrassArrayList.get(j).getXcord() amp;amp; ycord 1==GrassArrayList.get(j).getYcord()){
                        GrassArrayList.get(j).setLength((int)(GrassArrayList.get(j).getLength() getGrassGrowthRate()));
                }
            }
        }
    }
}
//using the run method
@Override
public void run(){
    tick();
}
public int getMoosePop(){
    return MooseArrayList.size();
}
public int getWolfPop(){
    return WolfArrayList.size();
}
public ArrayList<Grass> getGrassArrayList() {
    return GrassArrayList;
}
public void setGrassArrayList(ArrayList<Grass> grassArrayList) {
    GrassArrayList = grassArrayList;
}
public ArrayList<Moose> getMooseArrayList() {
    return MooseArrayList;
}
public void setMooseArrayList(ArrayList<Moose> mooseArrayList) {
    MooseArrayList = mooseArrayList;
}
public ArrayList<Wolf> getWolfArrayList() {
    return WolfArrayList;
}
public void setWolfArrayList(ArrayList<Wolf> wolfArrayList) {
    WolfArrayList = wolfArrayList;
}
}
  

** Класс**

 public class extends {
private int movewolf;
public Wolf(Simulator simulator){
    super(simulator);
}
@Override
public void eat(){
    setEnergy((getEnergy() getSimulator().getEnergyGainFromEatingMoose()));
}
@Override
public Animal reproduce(){
    Wolf wolf=new Wolf(getSimulator());
    wolf.setLocationX(getSimulator().randomInt(getSimulator().getMaxX()));
    wolf.setLocationY(getSimulator().randomInt(getSimulator().getMaxY()));
    wolf.setEnergy(getSimulator().getInitialEnergy());
    return wolf;
}
@Override
public Animal die(){
    return null;
}
@Override
public void move(){
    int moveX=(int)(Math.random()*2);
    int moveY=(int)(Math.random()*2);
    if (getLocationX()<getSimulator().getMaxX()amp;amp; getLocationX()>0 amp;amp; getLocationY()<getSimulator().getMaxY()amp;amp; getLocationY()>0){
        if (moveX==1){
            this.movewolf=getLocationX() 1;
            setLocationX(movewolf);
        }
        else{
            this.movewolf=getLocationX()-1;
            setLocationX(movewolf);
        }
        if (moveY==1){
            this.movewolf=getLocationY() 1;
            setLocationY(movewolf);
        }
        else{
            this.movewolf=getLocationY()-1;
            setLocationY(movewolf);
        }
    }
    else if (getLocationX()==getSimulator().getMaxX()){
        this.movewolf=getLocationX()-1;
        setLocationX(movewolf);
    }
    else if(getLocationX()==0){
        this.movewolf=getLocationX() 1;
        setLocationX(movewolf);
    }
    else if (getLocationY()==getSimulator().getMaxY()){
        this.movewolf=getLocationY()-1;
        setLocationY(movewolf);
    }
    else if (getLocationY()==0){
        this.movewolf=getLocationY() 1;
        setLocationY(movewolf);
    }
    else {
    }
}
}
  

** Класс**

 public class  extends Animal{
private int movemoose;
public Moose(Simulator simulator){
    super(simulator);
}
@Override
public void eat(){
    setEnergy((getEnergy() getSimulator().getEnergyGainFromEatingGrass()));
}
@Override
public Animal reproduce(){
    Moose moose=new Moose(getSimulator());
    moose.setLocationX(getSimulator().randomInt(getSimulator().getMaxX()));
    moose.setLocationY(getSimulator().randomInt(getSimulator().getMaxY()));
    moose.setEnergy(getSimulator().getInitialEnergy());
    return moose;
}
@Override
public Animal die(){
    return null;
}
@Override
public void move(){
    int moveX=(int)(Math.random()*2);
    int moveY=(int)(Math.random()*2);
    if (getLocationX()<getSimulator().getMaxX()amp;amp; getLocationX()>0 amp;amp; getLocationY()<getSimulator().getMaxY()amp;amp; getLocationY()>0){
        if (moveX==1){
            this.movemoose=getLocationX() 1;
            setLocationX(movemoose);
        }
        else{
            this.movemoose=getLocationX()-1;
            setLocationX(movemoose);
        }
        if (moveY==1){
            this.movemoose=getLocationY() 1;
            setLocationY(movemoose);
        }
        else{
            this.movemoose=getLocationY()-1;
            setLocationY(movemoose);
        }
    }
    else if (getLocationX()==getSimulator().getMaxX()){
        this.movemoose=getLocationX()-1;
        setLocationX(movemoose);
    }
    else if(getLocationX()==0){
        this.movemoose=getLocationX() 1;
        setLocationX(movemoose);
    }
    else if (getLocationY()==getSimulator().getMaxY()){
        this.movemoose=getLocationY()-1;
        setLocationY(movemoose);
    }
    else if (getLocationY()==0){
        this.movemoose=getLocationY() 1;
        setLocationY(movemoose);
    }
    else {
    }
}
}
  

** Класс**

 public class {
public Simulator getGrass(){
    return grass;
}
public void setGrass(Simulator grass){
    this.grass = grass;
}
public int getLength(){
    return length;
}
public void setLength(int length){
    this.length = length;
}
public int getInitialLength(){
    return initialLength;
}
public void setInitialLength(int initialLength){
    this.initialLength = initialLength;
}
public int getXcord(){
    return Xcord;
}
public void setXcord(int xcord){
    Xcord = xcord;
}
public int getYcord(){
    return Ycord;
}
public void setYcord(int ycord){
    Ycord = ycord;
}
private Simulator grass;
private int length;
private int initialLength=0;
private int Xcord;
private int Ycord;

public Grass(Simulator grass, int xcord, int ycord, int length){
    this.grass = grass;
    this.length = length;
    Xcord = xcord;
    Ycord = ycord;
    setLength(initialLength);
}
}
  

Комментарии:

1. Любой цикл for никогда не вызывает цикл for-ever, если указано ограничение. Я вижу предел, т. е. задан 2-й аргумент цикла for, поэтому это не вызовет проблемы. Есть ли какой-либо цикл while в упомянутых классах? и какова ценность simulate.getMaxX() и simulate.getMaxY()

2. maxX и maxY — это максимальные значения сетки 30×30, на которой все происходит. Я добавлю к первоначальному сообщению остальные классы для большей ясности

3. @MrunmayDeswandikar это явно неверно: for (int i = 0; true; ) {} имеет условие, но это бесконечный цикл.

4. Да, друг @AndyTurner! просто логическое значение также может быть условием! Идеальный

5. 1 с моей стороны ! 🙂

Ответ №1:

Я вижу проблему со второй строкой здесь:

 for (int i=0;i<simulate.getMaxX();i  ){
  for (int j=0;i<simulate.getMaxY();j  ){
  

Я думаю, что это должно быть j<simulate.getMaxY()

Комментарии:

1. Удаляете ли вы вложенный цикл for полностью или просто заменяете (int j=0;i<simulate.getMaxY();j ){ на j<simulate.getMaxY(); Я либо неправильно понимаю предлагаемое решение, либо ввожу его неправильно.

2. Строка должна быть for (int j=0; j<simulate.getMaxY(); j ){ . Предыдущее условие you никогда не становилось ложным, потому что переменная i из внешнего цикла не обновлялась во внутреннем цикле. Необходимо изменить только условие, проверенное во втором цикле; циклы должны оставаться, если нет другой проблемы.

3. Да, вы ожидали бы получить ошибку index out of bounds в цикле, в котором вы уменьшаете размер инициализирующего массива. Вместо использования .remove(j) попробуйте присвоить элементу в j значение null, а затем выполнить проход ПОСЛЕ завершения цикла, чтобы удалить все нулевые элементы в массиве.

4. Также похоже, что в вашем методе animalsEat лоси едят самих себя, а не траву.

5. да, это была проблема! теперь программа работает безупречно (за исключением некоторого изменения скорости!) спасибо вам всем!