Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's faster in Java 6 classloading?

The ProGuard home page lists as a feature:

  • Retargeting and preverifying existing class files for Java 6, to take full advantage of Java 6's faster class loading.

What is the difference in Java 6 that this refers to?

Is it significant?

Does it have impact on slowdowns caused by multithreading through the synchronized aspects of the default classloader?

like image 924
Ed Staub Avatar asked May 23 '12 17:05

Ed Staub


2 Answers

As the ProGuard FAQ hints:

the Java 6 compiler add preverification information to the class files

Looking at the Java Virtual Machine Specification Verification by Type Checking section:

If a Java virtual machine implementation ever attempts to perform verification by type inference on version 50.0 class files, it must do so in all cases where verification by typechecking fails.

This means that a Java virtual machine implementation cannot choose to resort to type inference in once case and not in another. It must either reject class files that do not verify via typechecking, or else consistently failover to the type inferencing verifier whenever typechecking fails.

The type checker requires a list of stack map frames for each method with a Code attribute. The type checker reads the stack map frames for each such method and uses these maps to generate a proof of the type safety of the instructions in the Code attribute.

Beginning with Java 6, class files 50.0 and above, a JVM may use type checking or type inference during class file verification. Before trying to understand performance benefits, what is type-checking and type-inference? This paper, Type-Checking and Type-Inference for Object-Oriented Programming Languages states:

A type system is an important part of a programming language. Languages that rely completely on run-time type-checking provide a high degree of flexibility but must usually sacrifice performance to do so.

And from Wikipedia on Type inference:

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. [...]

To obtain the information required to infer the type of an expression, the compiler either gathers this information as an aggregate and subsequent reduction of the type annotations given for its subexpressions, or through an implicit understanding of the type of various atomic values [...].

The OpenJDK HotSport Runtime Overview explains it nicely:

There are currently two methods of analyzing the bytecodes to determine the types and number of operands that will be present for each instruction. The traditional method is called “type inference”, and operates by performing an abstract interpretation of each bytecode and merging type states at branch targets or exception handles. The analysis iterates over the bytecode until a steady state for the types are found. If a steady state cannot be found, or if the resulting types violate some bytecode constraint, then a VerifyError is thrown. [...]

New in JDK6 is the second method for verification which is called “type verification”. In this method the Java compiler provides the steady-state type information for each branch or exception target, via the code attribute, StackMapTable. The StackMapTable consists of a number of stack map frames, each which indicates the types of the items on the expression stack and in the local variables at some offset in the method. The JVM needs to then only perform one pass through the bytecode to verify the correctness of the types to verify the bytecode. [...]

Type-checking means the JVM can do one pass through the class file to verify the type system; type-inference requires multiple passes. Is this a significant performance savings? It's probably relative to the total number of classes you have in your application and how many class files you have that are less than 50.0 (Java 6) and 50.0 and greater. If your application is not a performance critical application, I wouldn't worry about it; if it is, then you could run some benchmarks comparing performance differences when compiling your application to Java 5 and Java 6 class files.

like image 108
Dan Cruz Avatar answered Oct 13 '22 00:10

Dan Cruz


The improvement, according to this Java 6 white paper is:

The Java Virtual Machine's boot and extension class loaders have been enhanced to improve the cold-start time of Java applications. Prior to Java SE 6, opening the system jar file caused the Java Virtual Machine to read a one-megabyte ZIP index file that translated into a lot of disk seek activity when the file was not in the disk cache. With "class data sharing" enabled, the Java Virtual Machine is now provided with a "meta-index" file (located in jre/lib) that contains high-level information about which packages (or package prefixes) are contained in which jar files.

This helps the JVM avoid opening all of the jar files on the boot and extension class paths when a Java application class is loaded.

This particular improvement should not have any impact on running programs, as the classes from the system jar would already be loaded. It would only effect the first startup time of the application.

like image 44
Hari Menon Avatar answered Oct 12 '22 23:10

Hari Menon