Last active
September 1, 2019 04:21
-
-
Save cleantutorials/18b5dc73d983d1523473a3c2f2ee1509 to your computer and use it in GitHub Desktop.
The Dog POJO representing a Dog. The class has a faulty logic in the equals method which can lead to memory leaks if the object is used as key in Sets/Maps.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cleantutorials.jconsole.memory; | |
/** | |
* Dog represents a dog which can be uniquely identified by the MicroChip ID and | |
* can optionally have a name. | |
*/ | |
public class Dog { | |
/** The Unique MicroChip ID of the dog. */ | |
private int microChipID; | |
/** The name of the dog. */ | |
private String name; | |
/** Extra memory space for each instance to speed up the memory leak. */ | |
private byte[] toExpediteLeak; | |
Dog(int microChipID) { | |
this.microChipID = microChipID; | |
} | |
Dog(int microChipID, String name) { | |
/** | |
* On Creating a Dog object we allocate a 10Mb storage with each instance to | |
* expedite the memory leak. | |
*/ | |
this.toExpediteLeak = new byte[10000000]; | |
this.microChipID = microChipID; | |
this.name = name; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
if (obj == this) | |
return true; | |
if (!(obj instanceof Dog)) | |
return false; | |
Dog dog = (Dog) obj; | |
return dog.microChipID == microChipID && dog.name.equals(name); | |
} | |
@Override | |
public int hashCode() { | |
return microChipID; | |
} | |
/** | |
* @return MicroChip ID of the dog. | |
*/ | |
public int getMicroChipID() { | |
return microChipID; | |
} | |
/** | |
* @return name of the dog. | |
*/ | |
public String getName() { | |
return name; | |
} | |
/** | |
* @param name of the dog. | |
*/ | |
public void setName(String name) { | |
this.name = name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.cleantutorials.jconsole.memory; | |
import java.util.HashSet; | |
import java.util.Random; | |
import java.util.Set; | |
/** | |
* DogShelter class represents a Dog Shelter. Each instance maintains the list | |
* of dogs that are currently present in the shelter. This class is designed to | |
* demonstrate memory leak in Java due to design flaws and human errors. | |
*/ | |
public class DogShelter { | |
/** In Memory Store containing the dogs present in the shelter. */ | |
private Set<Dog> shelterDogs = new HashSet<Dog>(); | |
public static void main(String[] args) { | |
DogShelter shelter = new DogShelter(); | |
shelter.addAndRemoveRandomEntries(1000); | |
} | |
/** | |
* Adds the <code>Dog</code> object entry to the HashSet. | |
* | |
* @param microChipID An ID used to uniquely identify a dog. | |
* @param name Name of the dog. | |
*/ | |
public void addEntry(int microChipID, String name) { | |
Dog dog = new Dog(microChipID, name); | |
shelterDogs.add(dog); | |
} | |
/** | |
* Removes the <code>Dog</code> object from the HashSet | |
* | |
* @param microChipID An ID used to uniquely identify a dog. | |
*/ | |
public void removeEntry(int microChipID) { | |
Dog dog = new Dog(microChipID); | |
shelterDogs.remove(dog); | |
} | |
/** | |
* Generates random Dog Objects and add and remove the dog object serially. | |
* | |
* @param entriesCount Number of random entries to be added and removed from | |
* HashSet | |
*/ | |
public void addAndRemoveRandomEntries(int entriesCount) { | |
Random rand = new Random(); | |
String[] commonDogNames = { "Buddy", "Coco", "Charlie", "Cooper", "Maggie" }; | |
for (int i = 0; i <= entriesCount; i++) { | |
/** Generate a random dog name from the list of common dog names. */ | |
String randomDogName = commonDogNames[rand.nextInt(commonDogNames.length)]; | |
/** First add and then remove the entry from the HashSet. */ | |
addEntry(i, randomDogName); | |
removeEntry(i); | |
System.out.printf("Successfuly removed entry for %s with unique id %d.\n", randomDogName, i); | |
try { | |
/** | |
* Sleep before adding & removing new entry so that we can see the memory grow | |
* in JConsole. | |
*/ | |
Thread.sleep(500); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment