#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. да, это была проблема! теперь программа работает безупречно (за исключением некоторого изменения скорости!) спасибо вам всем!