繁体   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