奇怪的拼图 - 位置的内存访问无效

时间:2012-11-19 15:15:45

标签: java eclipse macos

我得到的错误信息是:

  

位置0x8的内存访问无效rip = 0x10cf4ab28

我正在做的是制作一个基本的股票回测系统,即在最新的Mac Os X上使用java + eclipse迭代各种算法的大量股票/历史数据。

我跟踪了似乎导致它的代码。一种用于获取海量数据的方法,被称为数千次。什么都没有保留,所以我认为没有内存泄漏。然而,在我得到内存错误之前,似乎有一个约7000次的设置限制我可以迭代它。

奇怪的是它在调试模式下完美运行。有谁知道Eclipse中的调试模式有何不同?

为jvm提供更多内存无济于事,并且使用-xint似乎可以正常工作。并且它再次在调试模式下完美运行。

public static List<Stock> getStockArray(ExchangeType e){
    List<Stock> stockArray = new ArrayList<Stock>();
    if(e == ExchangeType.ALL){
        stockArray.addAll(getStockArray(ExchangeType.NYSE));
        stockArray.addAll(getStockArray(ExchangeType.NASDAQ));
    }else if(e == ExchangeType.ETF){
        stockArray.addAll(etfStockArray);
    }else if(e == ExchangeType.NYSE){
        stockArray.addAll(nyseStockArray);
    }else if(e == ExchangeType.NASDAQ){
        stockArray.addAll(nasdaqStockArray);
    }
    return stockArray;
}

像这样的简单循环,迭代超过1000次,将导致内存错误。但不是在调试模式下。

for (Stock stock : StockDatabase.getStockArray(ExchangeType.ETF)) {
    System.out.println(stock.symbol);
}

2 个答案:

答案 0 :(得分:2)

Rob,如果您在评论中使用了很多建议,那么您的代码可以更有效率并使用更少的内存...这自然会解决您的原始问题。

public enum ExchangeType {
    ALL, ETF, NYSE, NASDAQ;

    private static EnumMap<ExchangeType, List<Stock> stocks;

    // Do this during your initialization routine, or if something changes
    public static loadStock(ExchangeType et, List<stock> stockList) {
        stocks.put(et, stockList);
    }

    public List<Stock> getStocks() {
        return stocks.get(this);
    }
}

然后,为了安全起见,您甚至可以实现自己的ImmutableList ...

public class ImmutableList<E> implements List<E> {
    private ArrayList<E> _internal;

    // Do something like this for modification methods
    public boolean add(E e) {
        throw new UnsupportedOperationException("This list is immutable!");
    }

    // Do something like this for access methods
    public E get(int index) {
        return _internal.get(index);
    }
}

这样可以控制你的记忆并大大提高性能!!

无论如何,如果这不能解决你的问题,很多人都说这可能是一个JVM错误。正如你所指出的那样,编译阈值(即-XX:CompileThreshold=100000)是一个快速而肮脏的解决方案,至少应该解决你的问题......

答案 1 :(得分:2)

这可能为时已晚,但对于遇到此问题的其他人来说,这就是解决问题的方法。 而不是使用增强的for循环,使用正常的。我很认真。

例如:

for(int stock = 0; stocks < StockDataBase.getStockArray(ExchangeType.ETF).size(); stock++)

你可以从那里拿走它。

这是因为每次增强的for循环循环时都要创建新对象,而不是常规的for循环。垃圾收集器可能没有足够的时间同时处理所有这些新对象。