为什么大数组java很慢

时间:2014-08-01 10:25:43

标签: java arrays garbage-collection

我创建了一个具有大长度,~150M元素的类的数组,按键排序(描述如下)。然后我构建一个简单的http服务器来反馈每个请求作为数组上的二进制搜索功能。 (我确定服务器的工作正常)

数据启动很好(很慢)。二进制搜索功能如预期的那样快。

问题是:响应只是快一段时间(10分钟,1小时......很多种时间范围),然后服务器花了很长时间(几分钟)为请求做二进制搜索功能,然后它& #39;快退,然后慢一会儿...... 虽然它很慢,但我检查服务器状态(htop),似乎jvm在GC中。

当我将大数组分成较小的数组时,问题不会发生,例如:10个15M元素的数组,我在搜索之前找到了目标数组。所以我想当我创建太大的数组

时,JVM会发生一些事情

(编辑:我把大数组分成碎片没有问题,因为我实现了#34; SiteInfo"对象是原生的,JVM中的大量对象减少了。所以问题引起了太多的对象我作为回复而创建,谢谢你们)

伙计们,你对我的问题有任何想法吗?

(我发布了我的代码,其中有一些Pseudocode,我认为它并不重要)

public static class Token2TopSite implements Comparable<Token2TopSite> {

    public final String token; // this is key for binary search
    public final SiteInfo[] topSites; // just data, not important at this question, I think

    public Token2TopSite(String token, SiteInfo[] topSites) {
        this.token = token;
        this.topSites = topSites;
    }

    @Override
    public int compareTo(Token2TopSite o) {
        return token.compareTo(o.token);
    }

    public static void main(String[] args) {
        Token2TopSite[] array = new Token2TopSite[150 * 1000000];
        ...; // init data for array, this runs properly
        Arrays.sort(array);
        startServerOnArray(array); // each request is a element search on the array
    }
} 

2 个答案:

答案 0 :(得分:4)

我认为Omry Yadan的诊断可能是正确的。这听起来像GC暂停,如果你在堆中有大量长期可达的对象,它们可能会特别糟糕。 GC执行&#34;完全&#34;时,GC必须遍历所有活动对象。集合。

(您可以通过启用GC日志记录,并将服务器性能较慢的时间与GC事件进行比较来确认这是确实与GC相关的问题。)

但是,我不同意他建议的解决方案。

更简单的解决方案是将JVM配置为使用&#34;并发&#34;而不是重写应用程序。或者&#34;低暂停&#34;垃圾收集器。只需在命令上设置一些参数即可启动Web服务器的JVM。

以下是一些Oracle参考资料:

答案 1 :(得分:1)

当有超过10万个对象时,JVM无法正常工作。 原因是垃圾收集器在寻找空闲内存时需要遍历所有对象,如果找不到任何可用内容的话。 一种解决方案是使用更少的对象。 我写了一个名为Banana的原始集合库,它实现了自己的内存管理。 它基本上创建了一个(或几个)int数组(int []),并允许您在其上构建动态数据结构(已经实现了几个,HashTable,LinkedList,LRUCache等)。