package com.blogspot.sdoulger;
public class LoopTest {
public LoopTest() {
super();
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
spendTime();
long end = System.currentTimeMillis();
System.out.println("Time spent: "+ (end-start));
LoopTest loopTest = new LoopTest();
}
private static void spendTime() {
for (int i =500000000;i>0;i--) {
}
}
}
11 回答
这实际上与HotSpot和默认选项值(Java HotSpot VM Options)相关联,这些值在客户端和服务器配置之间有所不同 .
来自Chapter 2的白皮书(The Java HotSpot Performance Engine Architecture):
所以真正的区别也在于编译器级别:
注意:jdk6 update 10(参见Update Release Notes:Changes in 1.6.0_10)的发布试图改善启动时间,但由于与热点选项不同的原因,使用更小的内核进行不同的打包 .
G. Demecki指出in the comments在64位版本的JDK中,多年来忽略
-client
选项 .见Windows java command:
旧版Java中最明显的直接差异是分配给
-client
而不是-server
应用程序的内存 . 例如,在我的Linux系统上,我得到:因为它默认为
-server
,但是使用-client
选项我得到:所以
-server
对于这个java
版本,大多数内存限制和初始分配要高得多 .但是,这些值可以针对体系结构,操作系统和jvm版本的不同组合进行更改 . jvm的最新版本删除了标志并重新移动了服务器和客户端之间的许多区别 .
还要记住,您可以使用
jvisualvm
查看正在运行jvm
的所有详细信息 . 如果您有用户或模块设置JAVA_OPTS
或使用更改命令行选项的脚本,这将非常有用 . 这还可以让您实时监控堆和permgen空间使用情况以及许多其他统计信息 .我刚才注意到的一个区别是,在“客户端”模式下,似乎JVM实际上将一些未使用的内存返回给操作系统 - 而使用“服务器”模式,一旦JVM抓取内存,它就不会给它背部 . 这就是它在Solaris上用Java6出现的方式(使用prstat -Z来查看分配给进程的内存量) .
-client和-server系统是不同的二进制文件 . 它们本质上是两个不同的编译器(JIT),它们连接到同一个运行时系统 . 客户端系统最适合需要快速的应用程序启动时间或占地面积小,服务器系统最适合整体性能最重要的应用 . 通常,客户端系统更适合GUI等交互式应用程序
我们用两个开关运行以下代码:
Note: 代码只编译一次!两次运行中的类都相同!
With -client:
java.exe -client -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest
花费的时间:766
With -server:
java.exe -server -classpath C:\ mywork \ classes com.blogspot.sdoulger.LoopTest
花费的时间:0
似乎对服务器系统进行了更积极的优化,删除了循环,因为它理解它不执行任何操作!
Reference
Oracle的在线文档提供了Java SE 7的一些信息 .
在Windows的java – the Java application launcher页面上,在64位JDK中忽略
-client
选项:然而(为了让事情变得有趣),在
-server
下它表明:Server-Class Machine Detection页面提供有关OS和体系结构选择的VM的信息 .
我不知道这对JDK 6有多大帮助 .
IIRC服务器VM在启动时执行更多热点优化,因此运行速度更快,但需要更长时间才能启动并使用更多内存 . 客户端VM推迟大部分优化以允许更快的启动 .
编辑添加:来自Sun的Here's some info,它不是非常具体,但会给你一些想法 .
来自Goetz - 实践中的Java并发:
我的重点 . 因人而异
IIRC,它涉及垃圾收集策略 . 理论上说,客户端和服务器在短期对象方面会有所不同,这对现代GC算法很重要 .
Here is a link在服务器模式下 . 唉,他们没有提到客户端模式 .
Here is a very thorough link一般关于GC;这是more basic article . 不确定是否地址-server vs -client,但这是相关材料 .
在No Fluff Just Stuff,Ken Sipe和Glenn Vandenburg都在就这类事情进行了很好的讨论 .
我没有发现2之间的启动时间有任何差异,但是使用“-server”(Solaris服务器,每个人都使用SunRays来运行应用程序),应用程序性能的改进非常小 . 那是在1.5以下 .
上次我看过这个,(并且不可否认它已经有一段时间了)我注意到的最大区别在于垃圾收集 .
IIRC:
服务器堆VM具有与客户端VM不同的代数,以及不同的垃圾收集算法 . This may not be true anymore
服务器VM将分配内存,而不是将其释放到操作系统
服务器VM将使用更复杂的优化算法,因此对优化有更大的时间和内存要求
如果您可以比较两个Java VM,一个客户端,一个使用jvisualvm工具的服务器,您应该看到垃圾收集的频率和效果以及代数的差异 .
我有一对屏幕截图显示差异非常好,但我无法重现,因为我有一个64位JVM只实现了服务器VM . (而且我也不会在我的系统上下载和纠缠32位版本 . )
这似乎不再是这种情况,尝试在服务器和客户端虚拟机的Windows上运行一些代码,我似乎得到了相同的生成模型对彼此而言...
当从1.4到1.7(“1.7.0_55”)版本进行迁移时 . 我们在这里观察的是,在客户端和服务器模式下分配给heapsize | permsize | ThreadStackSize参数的默认值没有这种差异 .
顺便说一句,(http://www.oracle.com/technetwork/java/ergo5-140223.html) . 这是从上面的链接获取的片段 .
ThreadStackSize在1.7中更高,而在通过Open JDK论坛时,有讨论称1.7版本的帧大小稍高 . 据信,根据您的应用程序行为,可以在运行时测量真正的差异