📜 ⬆️ ⬇️

Interesting job garbage collector

Problem
I started working on Java recently and faced an interesting problem related to dynamic redefinition of methods during execution. After exiting the overridden method, the object reference was lost. The solution to the problem was delayed due to the fact that it was on one computer and not on the other.


Code structure
I have a class Resident.

public class Resident {
/ * Variables * /
int age;
String trace;
boolean live;
int energy;
String name;
int id;
int x;
int y;
World world;
')
/ * Body * /
public void Turn () {
age ++;
}
}


From the Resident class is inherited Bot. And the Thurn method is redefined.

public class Bot extends Resident {
/ * Variables * /
Queue m;
Vector moves = new Vector ();

/ * Constrctors * /
public Bot ( int energy, String name, World World) {
this .energy = energy;
this .name = name;
this .trace = "" ;
if ( this .energy <1) {
this .live = false ;
} else {
live = true ;
}
this .world = world;
this .age = 0;
}

/ * Body * /
public void Turn () {
age ++;
energy--;
if (! moves.isEmpty ()) {
world.ResidentAction ( this , (ACTION) moves.lastElement ());
moves.remove (moves.size () - 1);
}
}
}


In the World class we have an array of residents.

public class World {
/*Variables*/
String name;
int width;
int height;
Resident[][] residents;

/*Constrctors*/
public World(String name, int height, int width) {
this .height = height;
this .name = name;
this .width = width;
this .residents = new Resident[height][width];
}

/*Body*/
public void AddBot() {
Bot b = new Bot(100, "B" , this );
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b) {
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b, int x, int y) {
residents[x][y] = b;
bX(x);
bY(y);
}

public void Turn() {
for ( int i = 0; i < width; i++) {
for ( int j = 0; j < height; j++) {
if (residents[i][j] != null ) {
residents[i][j].Turn();
if (!residents[i][j].isLive())
residents[i][j] = null ;
}
}
}
}
}


. , 1,2. .

public class Programm {

public static void main(String[] args) {
World w = new World( "Test1" , 100, 100);
Bot b = new Bote(20, "B" , w)
w.AddBot(b);
w.Turn();

}
}

* This source code was highlighted with Source Code Highlighter .
public class World {
/*Variables*/
String name;
int width;
int height;
Resident[][] residents;

/*Constrctors*/
public World(String name, int height, int width) {
this .height = height;
this .name = name;
this .width = width;
this .residents = new Resident[height][width];
}

/*Body*/
public void AddBot() {
Bot b = new Bot(100, "B" , this );
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b) {
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b, int x, int y) {
residents[x][y] = b;
bX(x);
bY(y);
}

public void Turn() {
for ( int i = 0; i < width; i++) {
for ( int j = 0; j < height; j++) {
if (residents[i][j] != null ) {
residents[i][j].Turn();
if (!residents[i][j].isLive())
residents[i][j] = null ;
}
}
}
}
}


. , 1,2. .

public class Programm {

public static void main(String[] args) {
World w = new World( "Test1" , 100, 100);
Bot b = new Bote(20, "B" , w)
w.AddBot(b);
w.Turn();

}
}

* This source code was highlighted with Source Code Highlighter .
public class World {
/*Variables*/
String name;
int width;
int height;
Resident[][] residents;

/*Constrctors*/
public World(String name, int height, int width) {
this .height = height;
this .name = name;
this .width = width;
this .residents = new Resident[height][width];
}

/*Body*/
public void AddBot() {
Bot b = new Bot(100, "B" , this );
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b) {
residents[1][2] = b;
bX(1);
bY(2);
}

public void AddBot(Bot b, int x, int y) {
residents[x][y] = b;
bX(x);
bY(y);
}

public void Turn() {
for ( int i = 0; i < width; i++) {
for ( int j = 0; j < height; j++) {
if (residents[i][j] != null ) {
residents[i][j].Turn();
if (!residents[i][j].isLive())
residents[i][j] = null ;
}
}
}
}
}


. , 1,2. .

public class Programm {

public static void main(String[] args) {
World w = new World( "Test1" , 100, 100);
Bot b = new Bote(20, "B" , w)
w.AddBot(b);
w.Turn();

}
}

* This source code was highlighted with Source Code Highlighter .

After leaving residents [i] [j] .Turn (), residents [i] [j] ended up being null. And then everything flew by exception. As I said on some computers, the problem was, and not on some.

Why
Because the bot is declared in the class Program. And when the bot method enters the Turn, the link to it is lost and the object is deleted at the output by the garbage collector. The problem is solved either like this:

public class Programm {
static Bot b;

public static void main (String [] args) {
World w = new World ( "Test1" , 100, 100);
b = new Bot (20, "" , w);
w.AddBot (b);
w.Turn ();

}
}


* This source code was highlighted with Source Code Highlighter .
Or by creating a bot in the World via the w.AddBot () method.

PS I may be wrong in determining the cause of this. I will be glad to hear opinions

Source: https://habr.com/ru/post/68577/


All Articles