簡體   English   中英

Java內存分配性能(SunOS與Windows)

[英]Java memory allocation performance (SunOS vs Windows)

我有一個非常簡單的單元測試,只分配了很多字符串:

public class AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Exception {

        for (int i = 0; i < 1000; i++) {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            System.out.println(i + ": " + (System.currentTimeMillis() - startTime) + "ms " + a.length());
        }

    }

}

在我的Windows PC(Intel Core Duo,2.2GHz,2GB)上,平均打印:

...
71: 47ms 17005
72: 47ms 17005
73: 46ms 17005
74: 47ms 17005
75: 47ms 17005
76: 47ms 17005
77: 47ms 17005
78: 47ms 17005
79: 47ms 17005
80: 62ms 17005
81: 47ms 17005
...

在SunOS(5.10 Generic_138888-03 sun4v sparc SUNW,SPARC-Enterprise-T5120)上:

...
786: 227ms 17005
787: 294ms 17005
788: 300ms 17005
789: 224ms 17005
790: 260ms 17005
791: 242ms 17005
792: 263ms 17005
793: 287ms 17005
794: 219ms 17005
795: 279ms 17005
796: 278ms 17005
797: 231ms 17005
798: 291ms 17005
799: 246ms 17005
800: 327ms 17005
...

兩台機器上的JDK版本均為1.4.2_18。 JVM參數是相同的,並且是:

–server –Xmx256m –Xms256m

誰能解釋為什么SUN超級服務器比較慢?

http://www.sun.com/servers/coolthreads/t5120/performance.xml

在SPARC(1.2Ghz)上,CPU的確確實要慢一些,並且正如Sun的一位工程師所回答的那樣,單線程應用程序的T2通常比現代Intel處理器慢3倍。 不過,他還指出,在多線程環境中,SPARC應該更快。

我使用GroboUtils庫進行了多線程測試,並測試了分配(通過串聯)和簡單的計算(a + = j * j)以測試處理器。 我得到以下結果:

1 thread : Intel : Calculations test : 43ms
100 threads : Intel : Calculations test : 225ms

1 thread : Intel : Allocations test : 35ms
100 threads : Intel : Allocations test : 1754ms

1 thread : SPARC : Calculations test : 197ms
100 threads : SPARC : Calculations test : 261ms

1 thread : SPARC : Allocations test : 236ms
100 threads : SPARC : Allocations test : 1517ms

SPARC通過在100個線程上勝過Intel來顯示其強大功能。

這里是多線程計算測試:

import java.util.ArrayList;
import java.util.List;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import junit.framework.TestCase;

public class TM1_CalculationSpeedTest extends TestCase {

    public void testCalculation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            long a = 0;
            for (int j = 0; j < 10000000; j++) {
                a += j * j;
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a);
        }

    }

}

這是多線程分配測試:

import java.util.ArrayList;
import java.util.List;

import junit.framework.TestCase;
import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;

public class TM2_AllocationSpeedTest extends TestCase {

    public void testAllocation() throws Throwable {

        List threads = new ArrayList();
        for (int i = 0; i < 100; i++) {
            threads.add(new Requester());   
        }
        MultiThreadedTestRunner mttr = new MultiThreadedTestRunner((TestRunnable[]) threads.toArray(new TestRunnable[threads.size()]));
        mttr.runTestRunnables(2 * 60 * 1000);

    }

    public class Requester extends TestRunnable {

        public void runTest() throws Exception {
            long startTime = System.currentTimeMillis();
            String a = "dummy";
            for (int j = 0; j < 1000; j++) {
                a += "allocation driven";
            }
            long endTime = System.currentTimeMillis();
            System.out.println(this + ": " + (endTime - startTime) + "ms " + a.length());
        }

    }

}

據我了解,基於UltraSPARC T2的計算機的目標是每瓦性能而不是原始性能。 您可以嘗試將分配時間除以功耗,然后看得出哪種數字。 :)

您運行1.4.2而不是1.6是有原因的嗎?

SunOS硬件較慢,而vm也可能較慢。

我不認為這正在衡量內存分配。 首先,在a += "allocation driven";中進行a += "allocation driven";大量的字符復制a += "allocation driven"; 但是我懷疑真正的瓶頸在於從Sun服務器上的應用程序到遠程工作站的網絡層從System.out.println(...)獲取輸出。

作為實驗,請嘗試將內部循環計數乘以10和100,然后查看是否相對於您的工作站“加速”了Sun服務器。

您可以嘗試的另一件事是將內部循環移動到單獨的過程中。 由於您可能在一次main調用中完成所有工作,因此JIT編譯器永遠不會獲得編譯它的機會。

(這樣的人為“微基准”總是容易受到此類影響。我傾向於不信任它們。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM