Asked  7 Months ago    Answers:  5   Viewed   37 times

Is there any real practical difference between "java -server" and "java -client"?

All I can find on Sun's site is a vague

"-server starts slower but should run faster".

What are the real differences? (Using JDK 1.6.0_07 currently.)

 Answers

98

This is really linked to HotSpot and the default option values (Java HotSpot VM Options) which differ between client and server configuration.

From Chapter 2 of the whitepaper (The Java HotSpot Performance Engine Architecture):

The JDK includes two flavors of the VM -- a client-side offering, and a VM tuned for server applications. These two solutions share the Java HotSpot runtime environment code base, but use different compilers that are suited to the distinctly unique performance characteristics of clients and servers. These differences include the compilation inlining policy and heap defaults.

Although the Server and the Client VMs are similar, the Server VM has been specially tuned to maximize peak operating speed. It is intended for executing long-running server applications, which need the fastest possible operating speed more than a fast start-up time or smaller runtime memory footprint.

The Client VM compiler serves as an upgrade for both the Classic VM and the just-in-time (JIT) compilers used by previous versions of the JDK. The Client VM offers improved run time performance for applications and applets. The Java HotSpot Client VM has been specially tuned to reduce application start-up time and memory footprint, making it particularly well suited for client environments. In general, the client system is better for GUIs.

So the real difference is also on the compiler level:

The Client VM compiler does not try to execute many of the more complex optimizations performed by the compiler in the Server VM, but in exchange, it requires less time to analyze and compile a piece of code. This means the Client VM can start up faster and requires a smaller memory footprint.

The Server VM contains an advanced adaptive compiler that supports many of the same types of optimizations performed by optimizing C++ compilers, as well as some optimizations that cannot be done by traditional compilers, such as aggressive inlining across virtual method invocations. This is a competitive and performance advantage over static compilers. Adaptive optimization technology is very flexible in its approach, and typically outperforms even advanced static analysis and compilation techniques.

Note: The release of jdk6 update 10 (see Update Release Notes:Changes in 1.6.0_10) tried to improve startup time, but for a different reason than the hotspot options, being packaged differently with a much smaller kernel.


G. Demecki points out in the comments that in 64-bit versions of JDK, the -client option is ignored for many years.
See Windows java command:

-client

Selects the Java HotSpot Client VM.
A 64-bit capable JDK currently ignores this option and instead uses the Java Hotspot Server VM.

Tuesday, June 1, 2021
 
juananrey
answered 7 Months ago
54

I prefer the first version to start a java application just because it has less pitfalls ("welcome to classpath hell"). The second one requires an executable jar file and the classpath for that application has to be defined inside the jar's manifest (all other classpath declaration will be silently ignored...). So with the second version you'd have to look into the jar, read the manifest and try to find out if the classpath entries are valid from where the jar is stored... That's avoidable.

I don't expect any performance advantages or disadvantages for either version. It's just telling the jvm which class to use for the main thread and where it can find the libraries.

Wednesday, June 2, 2021
 
TheTechnicalPaladin
answered 6 Months ago
34

First off, a little historical perspective on the topic, from one of the creators of Java. Next, Wikipedia has a moderately helpful section on Objective-C protocols. In particular, understand that Objective-C supports both formal protocols (which are explicitly declared with the @protocol keyword, the equivalent of a Java interface) and informal protocols (just one or more methods implemented by a class, which can be discovered via reflection).

If you adopt a formal protocol (Objective-C terminology for "implement an interface") the compiler will emit warnings for unimplemented methods, just as you would expect in Java. Unlike Java (as skaffman mentioned), if an Objective-C class implements the methods contained in a formal protocol, it is said to "conform" to that protocol, even if its interface doesn't explicitly adopt it. You can test protocol conformance in code (using -conformsToProtocol:) like this:

if ([myObject conformsToProtocol:@protocol(MyProtocol)]) {
    ...
}

NOTE: Apple's documentation states:

"This method determines conformance solely on the basis of the formal declarations in header files, as illustrated above. It doesn’t check to see whether the methods declared in the protocol are actually implemented—that’s the programmer’s responsibility."

As of Objective-C 2.0 (in OS X 10.5 "Leopard" and iOS), formal protocols can now define optional methods, and a class conforms to a protocol as long as it implements all the required methods. You can use the @required (default) and @optional keywords to toggle whether the method declarations that follow must or may be implemented to conform to the protocol. (See the section of Apple's Objective-C 2.0 Programming Language guide that discusses optional protocol methods.)

Optional protocol methods open up a lot of flexibility to developers, particularly for implementing delegates and listeners. Instead of extending something like a MouseInputAdapter (which can be annoying, since Java is also single-inheritance) or implementing a lot of pointless, empty methods, you can adopt a protocol and implement only the optional methods you care about. With this pattern, the caller checks whether the method is implemented before invoking it (using -respondsToSelector) like so:

if ([myObject respondsToSelector:@selector(fillArray:withObject:)]) {
    [myObject fillArray:anArray withObject:foo];
    ...
}

If the overhead of reflection becomes a problem, you can always cache the boolean result for reuse, but resist the urge to optimize prematurely. :-)

Tuesday, June 15, 2021
 
Francisunoxx
answered 6 Months ago
32

OopMap is a structure that records where object references (OOPs) are located on the Java stack. Its primary purpose is to find GC roots on Java stacks and to update the references whenever objects are moved within the Heap.

There are three kinds of OopMaps:

  1. OopMaps for interpreted methods. They are computed lazily, i.e. when GC happens, by analyzing bytecode flow. The best reference is the source code (with lots of comments), see generateOopMap.cpp. InterpreterOopMaps are stored in OopMapCache.
  2. OopMaps for JIT-compiled methods. They are generated during JIT-compilation and kept along with the compiled code so that VM can quickly find by instruction address the stack locations and the registers where the object references are held.
  3. OopMaps for generated shared runtime stubs. These maps are constructed manually by the developers - authors of these runtime stubs.

During GC JVM walks through all thread stacks. Each stack is parsed as a stream of stack frames. The frames are either interpreted or compiled or stubs. Interpreted frames contain information about Java method and bci (bytecode index). OopMapCache helps to find an OopMap corresponding to the given method and bci. The method of a compiled frame is discovered by instruction address lookup.

Wednesday, June 30, 2021
 
ManojGeek
answered 5 Months ago
65

Generally speaking, it's always preferable to let HotSpot compiler tune itself. Even using Server VM (-server) is default for 64bits and some 'server-class' machines.

-Xbatch was intended mostly for debugging as described in Steve Goldman's blog you pointed:

So the -Xbatch switch is not a particularly useful switch even in the pre-mustang days. It is somewhat useful for jvm developers since it tends to make a run more predictable and reproducible.

-Xcomp removes the ability to gather information for efficient compilation. From an Alex Turner's post:

One might think that -Xcomp would be a good idea from a performance point of view. However, it is not! The JIT compiler uses those 1000 iterations before compilation to gather information on how the method should be compiled for optimal efficiency. -Xcomp removes its ability to do so and thus we can actually see performance slip.

Without performance in mind, I've never seen using those flags to detect missing dependencies (and it may not work if some code is still interpreted) so IMHO, I would get rid of both.

Sunday, August 8, 2021
 
Kwadz
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share