Java中循环语句的垃圾收集

Java中循环语句的垃圾收集,java,for-loop,garbage-collection,nested-loops,Java,For Loop,Garbage Collection,Nested Loops,现在,我很少参加高尔夫比赛。对于一个特定的问题。我已经用java提交了一个答案,其中包含这样的嵌套循环 for(int i=0; i < 20_00_00_000; i++){ for(int j=0; j < 10_00_000; j++){ //declare some variables //do operations //modify variables outside of for loop } } for(

现在,我很少参加高尔夫比赛。对于一个特定的问题。我已经用java提交了一个答案,其中包含这样的嵌套循环

for(int i=0; i < 20_00_00_000; i++){
    for(int j=0; j < 10_00_000; j++){
        //declare some variables
        //do operations
        //modify variables outside of for loop
    }
}
for(int i=0; i < 20_00_00_000; i++){
    nextLoop(pass necessary args);
}

private void nextLoop(necessary args){
    for(int j=0; j < 10_00_000; j++){
        //declare some variables
        //do operations
        //modify variables outside of for loop
    }
}
但这只需要60%的时间。然后我意识到这和Garbase的嵌套循环集合有关。这两个代码的逻辑是相同的,但将内部循环分离为一个方法会使其速度更快。我假设这是因为垃圾收集是在
nextLoop()
方法完成后进行的,但是垃圾收集中存在一个关于第一个代码的嵌套for循环的问题

现在关于第一个代码,当父循环的下一次迭代开始时,内部for循环占用的内存不会自动被垃圾回收吗

实码 方法2(更快)

公共类MinPrimeFactorSum{
静态整数[]素数=新整数[20_000_000];
静态整数计数=0;
静态温度;
静态int-p;
静态长总=2;
公共静态void main(字符串[]args){
长启动=System.nanoTime();
int i=3;
对于(;i数学sqrt(i)){
打破
}
}
返回温度;
}
}
方法1(较慢)

公共类MinPrimeFactorSum{
静态整数[]素数=新整数[20_000_000];
静态整数计数=0;
静态温度;
静态int-p;
静态长总=2;
公共静态void main(字符串[]args){
长启动=System.nanoTime();
int i=3;
对于(;i数学sqrt(i)){
打破
}
}
//内环端
如果(i==temp){
素数[计数]=温度;
计数++;
}
总+=临时+2;
}
System.out.println(--i+“:“+total+”在“+(System.nanoTime()-start)/1000000+”毫秒内);
}
}

我只是在一系列测试之后才发布了这个问题。

是的,在第一个循环中,第二个循环的内存不会被垃圾收集。
未收集的原因是依赖性,第一个循环中的第二个循环依赖于第一个循环。因此,第二个循环中的东西依赖于第一个循环中的东西,它们彼此之间不完整,但在第二种情况下,两个循环都是独立的。一个循环不依赖于第二个循环,这就是垃圾收集的原因。

较慢的代码使用静态temp,而较快的代码在函数内声明本地temp

要使这两行相等,请尝试替换行
temp=i
int temp=i然后再次测量

编辑: 我注意到您的评论,您已经使它们都使用静态临时,并且调用该方法的版本更快。我认为区别在于JIT:它可能比优化内联版本更早地优化方法(然后内联)。另外,您的基准测试方法有点过于简单。Java代码的基准测试相当棘手。例如,请参阅,以获得对该主题的良好处理


顺便说一句,在我的例子中,两种情况下的计时只有0.5%的差异(3585和3595毫秒)。当我优化代码时(通过将对Math.sqrt的调用移到循环之外),它的运行速度是原来的两倍多,差别更为明显(1577对1687)。(这是在32位Windows上,Core 2 Quad Q8200。)

如果除了方法中的内部循环提取之外,代码实际上是相同的,我怀疑性能上的差异与垃圾收集有关。这可能是由于测量性能时存在缺陷,或者JIT优化中存在细微差异。无论如何,没有真正的代码和适当的基准测试(这很难),我们不能说。这只是一个示例代码,所以不要因为不必要的操作而责备我。请张贴正确的代码以进行相关评估。正如JBNizet所发布的,基准测试很难,而且您没有正确地进行=/GC不可能是性能差异的原因,因为代码中有0个要收集的对象:您只使用原语。这是一个JIT差异。在我在Mac上对Java8的测试中,第二个稍微快一点(3100毫秒对3400毫秒)。@JBNizet,原始代码posted正如我所说:JIT可能以不同的方式优化两个版本的代码。在我的机器上,两个版本的时间几乎相同
temp=i。这使得更快的方法变得更快。
public class MinPrimeFactorSum {

    static int[] primes = new int[20_000_000];
    static int count = 0;

    static int temp;
    static int p;
    static long total = 2;

    public static void main(String[] args) {

        long start = System.nanoTime();

        int i=3;
        for(; i<1_00_00_000; i += 2) {
            // Calling the inner loop as a method
            temp = getData(i);
            if( i == temp ) {
                primes[count] = temp;
                count++;
            }
            total += temp + 2;
        }
        System.out.println( --i + ": " + total + " in " + (System.nanoTime() - start)/1000000 + " milliseconds" );
    }

    // Inner Loop as a method
    private static int getData(int i) {
        temp = i;
        for(int index = 0;index < count; index++ ) {
            p = primes[index];
            if( i % p == 0 ) {
                temp = p;
                break;
            }
            if( p > Math.sqrt(i) ) {
                break;
            }
        }
        return temp;
    }

}
public class MinPrimeFactorSum {

    static int[] primes = new int[20_000_000];
    static int count = 0;

    static int temp;
    static int p;
    static long total = 2;

    public static void main(String[] args) {

        long start = System.nanoTime();

        int i=3;
        for(; i<1_00_00_000; i += 2) {
            temp = i;

            // Inner Loop Starts
            for(int index = 0;index < count; index++ ) {
                p = primes[index];
                if( i % p == 0 ) {
                    temp = p;
                    break;
                }
                if( p > Math.sqrt(i) ) {
                    break;
                }
            }
            // Inner Loop ends

            if( i == temp ) {
                primes[count] = temp;
                count++;
            }
            total += temp + 2;
        }
        System.out.println( --i + ": " + total + " in " + (System.nanoTime() - start)/1000000 + " milliseconds" );
    }

}