Reputation: 3108
I have been reading some stuffs on how the garbage collector works in Java, but I'm not sure to correctly understand what it is doing in reality. So I've been creating an ugly program...
The only thing it does is:
You hit the Remove button, and you remove the last element in the vector
public class modelTester {
public static Date getToday(){
Calendar cal = Calendar.getInstance();
return getDate(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH),0,0);
}
public static Date getDate(Integer year, Integer month, Integer day, Integer hour, Integer minute){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
final Vector<TreeMap<Date, Double>> v = new Vector<TreeMap<Date, Double>>();
JPanel panel = new JPanel(new FlowLayout());
JButton addButton = new JButton("add data");
JButton removeButton = new JButton("remove data");
JButton runGCButton = new JButton("run Garbage Collector");
panel.add(addButton);
panel.add(removeButton);
panel.add(runGCButton);
frame.getContentPane().add(panel);
addButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
TreeMap<Date, Double> data = new TreeMap<Date, Double>();
for (int i =0; i < 80000; i++){
data.put(new Date(getToday().getTime() - i), new Double(i));
}
v.add(data);
System.out.println("Adding Data => Vector Size = " + v.size());
}
});
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(v.size() !=0){
v.remove(v.size()-1);
}
System.out.println("Removing Data => Vector Size = " + v.size());
}
});
runGCButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Yeah, collecting garbage");
System.gc();
}
});
frame.setSize(150,150);
frame.setVisible(true);
}
}
After adding a few data and then removing everything, I am ending up with this memory consumption.
How come the program still use that amount of memory given that I don't have anymore references on the maps when removing them from the vector ?
Thanks for your help
EDIT AFTER USING VISUAL VM
Upvotes: 0
Views: 266
Reputation: 4411
As laune has said, the memory won't be reclaimed by the operating system. The JVM reserves a minimum amount of memory for the heap at startup (configured with the Xms setting) and grows it as necessary up to the maximum (the Xmx setting). It will never release memory back to the operating system.
To see how much of the heap space is actually being used, there are various tools available. VisualVM is one of the best free ones, it will show you the heap space usage, and will even give you a live histogram showing the amount of memory used by objects of each class.
Upvotes: 1