垃圾收集器不起作用

时间:2015-04-09 20:23:24

标签: java arraylist garbage-collection

我有一个程序从互联网下载股票数据,然后创建一个Stock对象,其中包含股票元数据和一系列历史价格。

起初我跑了超过20000只股票创建了它们并将它们输入到一个arraylist中以便将它们写入数据库(所有这些都在一次交易中)。这不是一个好主意,在我结束下载所有我希望程序因OutOfMemory而死的股票之前。

然后我决定,在我添加到arraylist的每500个股票后,我会将它们写入数据库并清理arraylist(arraylist.clear()为GC使其成为"魔术&# 34;)然后用另一个新的500股票填充arraylist并再次通过相同的过程。

那也没有用,因为OutOfMemory Exception,我的程序再次死亡。

我认为问题可能出现在我的代码中的其他地方,我做了一个实验并运行了相同的代码,但有一点不同:在我创建每个Stock对象后,我没有把它放入arraylist而我只是继续并重新创建Stock对象,而不将它们添加到arraylist中。

结果是我的程序根本没有消耗任何内存,这让我感到非常困惑和沮丧。

请帮我查看我的程序是否有问题

以下是代码的一些行:

第一个版本:

ArrayList<Stock> stocksData = new ArrayList<Stock>();
Stock stock;

BufferedReader br = null;
String line = "";

try {
    br = new BufferedReader(new FileReader(YAHOO_STOCKS_SYMBOLS));
    while ((line = br.readLine()) != null) {
        String[] stockMetaData = line.split(CSV_SPLIT);
        stock = new Stock();
        if (stockMetaData.length >= 4) {
            stock.setSymbol(stockMetaData[0]);
            stock.setName(stockMetaData[1]);
            stock.setExchange(stockMetaData[2]);
            stock.setCategory(stockMetaData[3]);
            DATA_UPDATER.updateStockData(stock, fromDate, toDate);
            if (stock.getHistoricalData() != null
                    && stock.getHistoricalData().size() > 0) {
                stocksData.add(stock);
            }
        }
    }
}

第二个版本:

ArrayList<Stock> stocksData = new ArrayList<Stock>();
Stock stock;

BufferedReader br = null;
String line = "";

try {
    br = new BufferedReader(new FileReader(YAHOO_STOCKS_SYMBOLS));
    while ((line = br.readLine()) != null) {
        String[] stockMetaData = line.split(CSV_SPLIT);
        stock = new Stock();
        if (stockMetaData.length >= 4) {
            stock.setSymbol(stockMetaData[0]);
            stock.setName(stockMetaData[1]);
            stock.setExchange(stockMetaData[2]);
            stock.setCategory(stockMetaData[3]);
            DATA_UPDATER.updateStockData(stock, fromDate, toDate);
            if (stock.getHistoricalData() != null
                    && stock.getHistoricalData().size() > 0) {
                stocksData.add(stock);
            }
        }
        if (stocksData.size() == 500) {
            WritingUtils.getInstance().updateStocks(stocksData);
            stocksData.clear();
            // I also tried
            //System.gc();
        }
    }
}

我添加了更多信息:

股票领域:

protected String _symbol;

protected String _name;

protected String _exchange;

protected Date _upToDate;

protected ArrayList<DailyData> _historicalData;

DailyData字段:

private Date _date;

private double _open;

private double _close;

private double _adjClose;

private double _high;

private double _low;

private double _volume;

1 个答案:

答案 0 :(得分:1)

首先,我将首先使用JVisualVM(JDK附带的)工具对应用程序进行概要分析,然后准确指出堆中保留的对象。

其次,没有&#39; clean()&#39; ArrayList上的方法,因此不清楚您实际采取了哪些措施来阻止您的列表无限增长。

最后,考虑在程序中设置条件断点以“捕捉”#39;当名单超出你的预期时。

编辑:如果你现在要问的是:

&#39;我的OutOfMemoryError可以归结为:

protected ArrayList<DailyData> _historicalData;

正在增长并导致记忆压力?&#39;

答案是肯定的。您是否也尝试为您的流程增加内存?尝试运行:

java -Xms1g -Xmx1g *yourProgram*

看它是否仍然失败。您可能没有泄漏,可能只是您的应用程序需要更多内存来处理您正在做的事情。