了解使用地图和矢量时垃圾收集器在Java 7中的工作方式

时间:2014-06-20 04:23:30

标签: java vector map garbage-collection

我一直在阅读有关垃圾收集器如何在Java中工作的一些内容,但我不确定是否正确理解它在现实中的作用。所以我一直在创造一个丑陋的程序......

它唯一能做的就是:

  • 您点击添加按钮,然后创建一个添加到矢量
  • 的80K元素的TreeMap
  • 您点击了删除按钮,然后删除了向量中的最后一个元素

        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);
    
            }
        }
    

添加一些数据然后删除所有内容后,我最终会消耗此内存。

enter image description here

为什么程序仍然使用那么多的内存,因为当从向量中删除时,我不再在地图上引用?

感谢您的帮助

使用VISUAL VM后编辑

enter image description here

1 个答案:

答案 0 :(得分:1)

正如laune所说,操作系统不会回收内存。 JVM在启动时为堆保留最小内存量(使用Xms设置配置),并在必要时将其增大到最大值(Xmx设置)。它永远不会将内存释放回操作系统。

要查看实际使用了多少堆空间,可以使用各种工具。 VisualVM是最好的免费之一,它会显示堆空间使用情况,甚至会给你一个实时直方图,显示每个类对象使用的内存量。