我有一个程序从互联网下载股票数据,然后创建一个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;
答案 0 :(得分:1)
首先,我将首先使用JVisualVM(JDK附带的)工具对应用程序进行概要分析,然后准确指出堆中保留的对象。
其次,没有&#39; clean()
&#39; ArrayList
上的方法,因此不清楚您实际采取了哪些措施来阻止您的列表无限增长。
最后,考虑在程序中设置条件断点以“捕捉”#39;当名单超出你的预期时。
编辑:如果你现在要问的是:
&#39;我的OutOfMemoryError可以归结为:
protected ArrayList<DailyData> _historicalData;
正在增长并导致记忆压力?&#39;
答案是肯定的。您是否也尝试为您的流程增加内存?尝试运行:
java -Xms1g -Xmx1g *yourProgram*
看它是否仍然失败。您可能没有泄漏,可能只是您的应用程序需要更多内存来处理您正在做的事情。