Sie sind auf Seite 1von 14

java.exe is how you start the JVM. javac.exe is how you start the compiler.

Java Virtual Machine Support for Non-Java Languages


The following topics are covered:

Introduction Static and Dynamic Typing The Challenge of Compiling Dynamically Typed Languages The invokedynamic Instruction Resources

Introduction
The Java SE platform enables the development of applications with the following features:

Can be written once and run anywhere Can be run securely because of the Java sandbox security model Easy to package and deliver

The Java SE platform also provides robust support with respect to the following areas (and more):

Concurrency Garbage collection Reflective access to classes and objects JVM Tool Interface (JVM TI): A native programming interface for use by tools. It provides both a way to inspect the state and to control the execution of applications running in the JVM.

Oracle's HotSpot JVM also offers the following tools and features:

DTrace: A comprehensive dynamic tracing utility that monitors the behavior of applications programs as well as the operating system itself. Performance optimizations PrintAssembly: A Java HotSpot option that prints assembly code for bytecoded and native methods.

The Java SE 7 platform enables non-Java languages to exploit the infrastructure and potential performance optimizations of the JVM. The key mechanism is the invokedynamic instruction, which simplifies the implementation of compilers and runtime systems for dynamically typed languages on the JVM.

Static and Dynamic Typing


A programming language is statically typed if it performs type checking at compile time. Type checking is the process of verifying that a program is type safe. A program is type safe if the arguments of all of its operations are the correct type. Java is a statically typed language. All typed information for class and instance variables, method parameters, return values, and other variables is available when a program is compiled. The compiler for the Java programming language uses this type information to produce strongly typed bytecode, which can then be efficiently executed by the JVM at runtime. The following example of a Hello World program demonstrates static typing. Types are shown in bold.

import java.util.Date; public class HelloWorld { public static void main(String[] argv) { String hello = "Hello "; Date currDate = new Date(); for (String a : argv) { System.out.println(hello + a); System.out.println("Today's date is: " + currDate); } } }
A programming language is dynamically typed if it performs type checking at runtime. JavaScript and Ruby are examples of dynamically typed languages. These languages verify at runtime, rather than at compile time, that values in an application conform to expected types. These languages typically do not have any type information available at compile time. The type of an object can be determined only at runtime. Hence, in the past, it was difficult to efficiently implement them on the JVM. The following is an example of the Hello World program written in the Ruby programming language:

#!/usr/bin/env ruby require 'date' hello = "Hello " currDate = DateTime.now ARGV.each do|a| puts hello + a puts "Date and time: " + currDate.to_s end
Note that every name is introduced without a type declaration. Also, the main program is not located inside of a holder type (the Java class HelloWorld. The Ruby equivalent of the Java for loop is inside the dynamic type of the variable ARGV. The body of the loop is contained in a block called a closure, a common feature in dynamic languages.

Statically Typed Languages Are Not Necessarily Strongly Typed Languages


A programming language that features strong typing specifies restrictions on the types of values supplied to its operations. If a computer language implements strong typing, it prevents the execution of an operation if its arguments have the wrong type. Conversely, a language that features weak typing would implicitly convert (or cast) arguments of an operation if those arguments have wrong or incompatible types. Statically typed programming languages can employ strong typing or weak typing. Similarly, dynamically typed languages can also apply strong typing or weak typing. For example, the Ruby programming language is dynamically typed and strongly typed. Once a variable has been initialized with a value of some type, the Ruby programming language will not implicitly convert the variable into another data type. The Ruby programming language would not allow the following:

a = "40" b = a + 2
In this example, the Ruby programming language will not implicitly cast the number 2, which has a Fixnum type, to a string.

The Challenge of Compiling Dynamically Typed Languages


Consider the following dynamically typed method, addtwo, that adds any two numbers (which can be of any numeric type) and returns the sum:

def addtwo(a, b) a + b; end


Suppose your organization is implementing a compiler and runtime system for the programming language in which the method addtwo is written. In a strongly typed language, whether typed statically or dynamically, the behavior of + (the addition operator) depends on the types of the operands. A compiler for a staticallytyped language chooses which implementation of + is appropriate based on the static types of a and b. For example, a Java compiler implements + with the iadd JVM instruction if the types of a and b are int. The addition operator will be compiled to a method call because the JVM's iadd instruction requires the operand types to be statically known. In contrast, a compiler for a dynamically-typed language must defer the choice until runtime. The statement a + b is compiled as the method call +(a, b), where + is the method name. (Note a method named + is permitted in the JVM but not in the Java programming language.) Suppose then that the runtime system for the dynamically-typed language is able to identify that a and b are variables of integer type. The runtime system would prefer to call an implementation of + that is specialized for integer types rather than arbitrary object types. The challenge of compiling dynamically typed languages is how to implement a runtime system that can choose the most appropriate implementation of a method or function after the program has been compiled. Treating all variables as objects of Object type would not work efficiently; the Object class does not contain a method named +. Java SE 7 introduces the invokedynamic instruction that enables the runtime system to customize the linkage between a call site and a method implementation. In this example, the invokedynamic call site is +. Aninvokedynamic call site is linked to a method by means of a bootstrap method, which is a method specified by the compiler for the dynamically-typed language that is called once by the JVM to link the site. Assuming the compiler emitted an invokedynamic instruction that invokes +, and assuming that the runtime system knows about the method adder(Integer,Integer), the runtime can link the invokedynamic call site to the adder method as follows: IntegerOps.java

class IntegerOps { public static Integer adder(Integer x, Integer y) { return x + y; } }


Example.java

import import import import

java.util.*; java.lang.invoke.*; static java.lang.invoke.MethodType.*; static java.lang.invoke.MethodHandles.*;

class Example { public static CallSite mybsm( MethodHandles.Lookup callerClass, String dynMethodName, MethodType dynMethodType) throws Throwable { MethodHandle mh = callerClass.findStatic( Example.class, "IntegerOps.adder", MethodType.methodType(Integer.class, Integer.class, Integer.class)); if (!dynMethodType.equals(mh.type())) { mh = mh.asType(dynMethodType); } } }
In this example, the IntegerOps class belongs to the library that accompanies the dynamic language's runtime system. The method Example.mybsm is a bootstrap method that links the invokedynamic call site to the adder method. The object callerClass is a lookup object, which is a factory for creating method handles. The method MethodHandles.Lookup.findStatic (called from the callerClass lookup object) creates a static method handle for the method adder. Note: This bootstrap method links an invokedynamic call site only to the code defined in the adder method, and it assumes that the arguments given to the invokedynamic call site will be Integer objects. A bootstrap method requires additional code to properly link invokedynamic call sites to the appropriate code to execute if the parameters of the bootstrap method (in this example, callerClass, dynMethodName, and dynMethodType) vary. The classes java.lang.invoke.MethodHandles and java.lang.invoke.MethodHandle conta in various methods that create method handles based on existing method handles. This example calls the method asType if the method type of the method handle mh does not match the method type specified by the parameter dynMethodType. This enables the bootstrap method to link invokedynamic call sites to Java methods whose method types do not exactly match. The ConstantCallSite instance returned by the bootstrap method represents a call site to be associated with a distinct invokedynamic instruction. The target for a ConstantCallSite instance is permanent and can never be changed. In this case there is only one Java method, adder, which is a candidate for executing the call site. Note that this method does not have to be a Java method. Instead, if there were several such methods being available to the runtime system, each handling different argument types, the bootstrap method mybsm could dynamically select the correct method, based on the dynMethodType argument.

return new ConstantCallSite(mh);

The invokedynamic Instruction


The invokedynamic instruction simplifies and potentially improves implementations of compilers and runtime systems for dynamic languages on the JVM. The invokedynamic instruction does this by

allowing the language implementer to define custom linkage behavior. This contrasts with other JVM instructions such as invokevirtual, in which linkage behavior specific to Java classes and interfaces is hard-wired by the JVM. Each instance of an invokedynamic instruction is called a dynamic call site. A dynamic call site is originally in an unlinked state, which means that there is no method specified for the call site to invoke. As previously mentioned, a dynamic call site is linked to a method by means of a bootstrap method. A dynamic call site's bootstrap method is a method specified by the compiler for the dynamically-typed language that is called once by the JVM to link the site. The object returned from the bootstrap method permanently determines the call site's behavior. The invokedynamic instruction contains a constant pool index (in the same format as for the other invoke instructions). This constant pool index references a CONSTANT_InvokeDynamic entry. This entry specifies the bootstrap method (a CONSTANT_MethodHandle entry), the name of the dynamically linked method, and the argument types and return type of the call to the dynamically linked method. The following is an example of an invokedynamic instruction. In this example, the runtime system links the dynamic call site specified by this invokedynamic instruction (which is +, the addition operator) to theIntegerOps.adder method by using the bootstrap method Example.mybsm. The methods adder and mybsm are defined in the section The Challenge of Compiling Dynamically Typed Languages (line breaks have been added for clarity):

invokedynamic InvokeDynamic REF_invokeStatic: Example.mybsm: "(Ljava/lang/invoke/MethodHandles/Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite;": +: "(Ljava/lang/Integer; Ljava/lang/Integer;) Ljava/lang/Integer;";
Note: The bytecode examples in these sections use the syntax of the ASM Java bytecode manipulation and analysis framework. Invoking a dynamically linked method with the invokedynamic instruction involves the following steps: 1. 2. Defining the Bootstrap Method Specifying Constant Pool Entries Using the invokedynamic Instruction

3.

1. Defining the Bootstrap Method


At runtime, when the JVM first encounters an invokedynamic instruction, it calls the bootstrap method. This method links the name specified by the invokedynamic instruction with the code that should be executed (the target method), which is referenced by a method handle. If the JVM executes the same invokedynamic instruction again, it does not call the bootstrap method; it automatically calls the linked method handle. The bootstrap method's return type must be java.lang.invoke.CallSite. A CallSite object represents the linked state of an invokedynamic instruction and the method handle to which it is linked. The bootstrap method takes three or more parameters:

1. 2. 3. 4.

A MethodHandles.Lookup object, which is a factory for creating method handles in the context of the invokedynamic instruction. A String object, the method name mentioned in the dynamic call site. A MethodType object, the resolved type signature of the dynamic call site. Optionally, one or more additional static arguments to the invokedynamic instruction. These arguments, drawn from the constant pool, are intended to help language implementers safely and compactly encode additional metadata useful to the bootstrap method. In principle, the name and extra arguments are redundant since each call site could be given its own unique bootstrap method. However, such a practice is likely to produce large class files and constant pools

See the section The Challenge of Compiling Dynamically Typed Languages for an example of a bootstrap method.

2. Specifying Constant Pool Entries


As mentioned previously, the invokedynamic instruction contains a reference to an entry in the constant pool with the tag CONSTANT_InvokeDynamic. This entry contains references to other entries in the constant pool and references to attributes. This section briefly describes constant pool entries used by the invokedynamic instruction. For more information, see the java.lang.invoke package documentation and The Java Virtual Machine Specification.

Example Constant Pool


The following is an excerpt from the constant pool for the class Example, which contains the bootstrap method Example.mybsm that links the method + with the Java method adder:

class #159; // #47 Utf8 "adder"; // #83 Utf8 "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;"; // #84 Utf8 "mybsm"; // #87 Utf8 "(Ljava/lang/invoke/MethodHandles/Lookup;Ljava/lang/String;Ljava/lang/i nvoke/MethodType;) java/lang/invoke/CallSite;"; // #88 Utf8 "Example"; // #159 Utf8 "+"; // #166 // ... NameAndType #83 #84; // #228 Method #47 #228; // #229 MethodHandle 6b #229; // #230 NameAndType #87 #88; // #231 Method #47 #231; // #232 MethodHandle 6b #232; // #233 NameAndType #166 #84; // #234 Utf8 "BootstrapMethods"; // #235 InvokeDynamic 0s #234; // #236 The constant pool entry for the invokedynamic instruction in this example contains three values: CONSTANT_InvokeDynamic tag Unsigned short of value 0 Constant pool index #234.

The value 0 refers to the first bootstrap method specifier in the array of specifiers stored in the BootstrapMethods attribute. Bootstrap method specifiers are not in the constant pool table; they are contained in this separate array of specifiers. Each bootstrap method specifier contains an index to a CONSTANT_MethodHandle constant pool entry, which is the bootstrap method itself. The following is an excerpt from the same constant pool that shows the BootstrapMethods attribute, which contains the array of bootstrap method specifiers:

[3] { // Attributes // ... Attr(#235, 6) { // BootstrapMethods at 0x0F63 [1] { // bootstrap_methods { // bootstrap_method #233; // bootstrap_method_ref [0] { // bootstrap_arguments } // bootstrap_arguments } // bootstrap_method } } // end BootstrapMethods } // Attributes The constant pool entry for the bootstrap method mybsm method handle contains three values: CONSTANT_MethodHandle tag Unsigned byte of value 6 Constant pool index #232.

The value 6 is the subtag REF_invokeStatic. See the next section, 3. Using the invokedynamic Instruction, for more information about this subtag.

3. Using the invokedynamic Instruction


The following bytecode uses the invokedynamic instruction to call the bootstrap method mybsm, which links the dynamic call site (+, the addition operator) to the method adder. This example uses the + method to add the numbers 40 and 2 (line breaks have been inserted for clarity):

bipush 40; invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/Integer;"; iconst_2; invokestatic Method java/lang/Integer.valueOf:"(I)Ljava/lang/Integer;"; invokedynamic InvokeDynamic REF_invokeStatic: Example.mybsm: "(Ljava/lang/invoke/MethodHandles/Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite;": +: "(Ljava/lang/Integer; Ljava/lang/Integer;) Ljava/lang/Integer;";

The first four instructions put the integers 40 and 2 on the stack and boxes them in the java.lang.Integer wrapper type. The fifth instruction invokes a dynamic method. This instruction refers to a constant pool entry with aCONSTANT_InvokeDynamic tag:

REF_invokeStatic: Example.mybsm: "(Ljava/lang/invoke/MethodHandles/Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite;": +: "(Ljava/lang/Integer; Ljava/lang/Integer;) Ljava/lang/Integer;"; Four bytes follow the CONSTANT_InvokeDynamic tag in this entry:
The first two bytes form a reference to a CONSTANT_MethodHandle entry that references a bootstrap method specifier:

REF_invokeStatic: Example.mybsm: "(Ljava/lang/invoke/MethodHandles/Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite;"


As mentioned previously, this reference to a bootstrap method specifier is not in the constant pool table; it is contained in a separate array defined by a class file attribute named BootstrapMethods. The bootstrap method specifier contains an index to a CONSTANT_MethodHandle constant pool entry, which is the bootstrap method itself. Three bytes follow this CONSTANT_MethodHandle constant pool entry:

The first byte is the subtag REF_invokeStatic. This means that this bootstrap method will create a method handle for a static method; note that this bootstrap method is linking the dynamic call site with the static Java method adder. The next two bytes form a CONSTANT_Methodref entry that represents the method for which the method handle is to be created:

o o o o o

Example.mybsm: "(Ljava/lang/invoke/MethodHandles/Lookup; Ljava/lang/String; Ljava/lang/invoke/MethodType;) Ljava/lang/invoke/CallSite;"


In this example, the fully qualified name of the bootstrap method is Example.mybsm; the argument types are MethodHandles.Lookup, String, and MethodType; and the return type is CallSite.

The next two bytes form a reference to a CONSTANT_NameAndType entry:

+: "(Ljava/lang/Integer; Ljava/lang/Integer;) Ljava/lang/Integer;"

This constant pool entry specifies the method name (+), argument types (two Integer instances), and return type of the dynamic call site (Integer). In this example, the dynamic call site is presented with boxed integer values, which exactly match the type of the eventual target, the adder method. In practice, the argument and return types do not need to exactly match. For example, the invokedynamic instruction could pass either or both of its operands on the JVM stack as primitive int values. Either or both operands could also be untyped Object values. The invokedynamic instruction could also receive its result as a primitive int value, or an untyped Object value. In any case, the dynMethodType argument to mybsm will accurately describe the method type required by the invokedynamic instruction. Independently, the adder method could also have been given primitive or untyped arguments or return values. The bootstrap method is responsible for making up any difference between the dynMethodType and the type of theadder method. As shown in the code, this is easily done with an asType call on the target method.

Resources

java.lang.invoke package documentation The Da Vinci Machine Project

Primer: Difference between javac and JIT


A compiler or translatortranslatesone languageto anotherlanguage.Usually a high level language (suchas Java or C++or whatever)gets translatedto a lower level language suchas machinecodeor bytecode.The latter actually is machinecodefor a non-existingmachine.After translation(or compilation)is done, you still havetoexecute or interpret the resultinglanguage, or instruction set as they call it whenwere talkinglow level languages,to get your results. Now, howdoes this all apply to this mysteriousJava bizniz. Supposeyou write somethinglike this:

int a= 42; int b= 1; int c= a+b;


The Javaccompilermight translatethis codeinto somethinglike this:

move a, 42 move b, 1 load a add b store c

The stuff aboverepresentsthe byte code, generatedby the Javaccompiler. Whenyour JVMstarts, it interpretsthesesimple instructionsand gets the job done, i.e. it acts as if it werea simpleCPUexecuting(this is synonymousto interpreting)thesesimple instructions. Hotspotcompilerstry to makean educatedguesswhetheror not they shouldcompilethe byte codewhenthe job has got to be done. Thesesimpleinstructionsabovecan be further translatedto real machinecode, say a SPARCprocessormachinecodeor a Pentiummachinecode. Whenreal machinecodeis generated,there is no needanymorefor the JVMinterpreterto interpretthose byte codes;the real CPUcan handlethe job, causinga major speedincrease.The task of translatingthosebyte codes to real machinecodeis the responsibility of the JIT compiler; it translatesJavabyte codeto real machinecode. Of course,this real machinecodediffers per processor,i.e. Pentiummachinecodecannotbe run on a SPARCprocessoror vice versa. Thats why thoseJIT compilersdiffer per platform. Now, this is what everyJVMis facing: shouldit further translatethosebyte codes(usingthat JIT compiler) or shouldit interpret (or execute)thesethingsitself? JIT compilationis just what it says: just in time compilation. Facingthe choiceof interpretingthosebyte codesitself (beingslow) or compilingit into real machinecode(by activatingthe JIT compiler) first and then let the real processor do the job, so the real machinecodecould get executed(or interpreted)by the real CPUis quite a choiceto make. Supposea particularpieceof byte codemust be executedor interpreted.What to do? Interpretit a bit sloweror compileit to real machinecodeand let the CPUdo the dirty job? Whatif this pieceof codegets executedonly once?Furthercompilationinto real machinecodecould/wouldbe a waste. But what if this pieceof codehappensto be the body of a loop that gets executeda zillion times?Compilingit into real machinecodeoncewouldnt be muchoverheadcomparedto the increaseof speed.This is wherethe hotspotcompilerscomein, i.e. they try to makean educatedguesswhetheror not they shouldcompilethe byte codewhenthe job has got to be done. The behaviourof thosehot spot compilersit quite fascinating;loops start off quite slowlyand after a coupleof iterationsthe hot spot compiler sees that its dealingwith a hot spot (hencethe name)of code, so it translatesthe byte codesinto machinecode, so the JVMcan relinquishcontrol and let the real CPUdo the job.

What is the difference between JRE,JVM and JDK? JDK (Java Development Kit)
Java Developer Kit contains tools needed to develop the Java programs, and JRE to run the programs. The tools include compiler (javac.exe), Java application launcher (java.exe), Appletviewer, etc Compiler converts java code into byte code. Java application launcher opens a JRE, loads the class, and invokes its main method. You need JDK, if at all you want to write your own programs, and to compile the m. For running java programs, JRE is sufficient. JRE is targeted for execution of Java files

i.e. JRE = JVM + Java Packages Classes(like util, math, lang, awt,swing etc)+runtime libraries. JDK is mainly targeted for java development. I.e. You can create a Java file (with the help of Java packages), compile a Java file and run a java file

JRE (Java Runtime Environment)


Java Runtime Environment contains JVM, class libraries, and other supporting files. It does not contain any development tools such as compiler, debugger, etc. Actually JVM runs the program, and it uses the class libraries, and other supporting files provided in JRE. If you want to run any java program, you need to have JRE installed in the system

The Java Virtual Machine provides a platform-independent way of executing code; programmers can concentrate on writing software, without having to be concerned with how or where it will run. If u just want to run applets (ex: Online Yahoo games or puzzles), JRE needs to be installed on the machine.

JVM (Java Virtual Machine)


As we all aware when we compile a Java file, output is not an exe but its a .class file. .class file consists of Java byte codes which are understandable by JVM. Java Virtual Machine interprets the byte code into the machine code depending upon the underlying operating system and hardware combination. It is responsible for all the things like garbage collection, array bounds checking, etc JVM is platform dependent. The JVM is called virtual because it provides a machine interface that does not depend on the underlying operating system and machine hardware architecture. This independence from hardware and operating system is a cornerstone of the write-once run-anywhere value of Java programs. There are different JVM implementations are there. These may differ in things like performance, reliability, speed, etc. These implementations will differ in those areas where Java specification doesnt mention how to implement the features, like how the garbage collection process works is JVM dependent, Java spec doesnt define any specific way to do this.

What is difference between JDK,JRE and JVM?


To compile the java program we requires compiler. In jdk, we have javac.exe, which is responsible for compilation of the program, which generates bytecode (.class file) . To run the bytecode (.class file), we require java run time environment JRE, which is given by java.exe. In jdk as well as in jre we have java.exe. javac.exe and java.exe both launches the jvm for compilation as well as to run the program?

Difference between JDK, JRE, JVM


JDK or the Java Development Kit is a set of a Java compiler, a Java interpreter, developer tools, Java API libraries, documentation which can be used by Java developers to develop Java-based applications. JRE or the Java Runtime Environment is a minimum set that includes a Java interpreter, Java API libraries, Java browser plug-in, which make up the minimum environment to execute Java-based applications. The JVM or Java Virtual Machine is the core of the Java platform and is a part of both the JDK and JRE that translates Java bytecodes and executes them as native code on the client machine. JDK includes a JRE as as subset. JDK is a software bundle consists of binary files such as (javac,java,javadoc,jdb,javap,rmic....),java library files (both old and new)and some header files. Development environment requires this software. JRE is also a software bundle same as JDK excluded with some binary files( especially compiler - javac and rmic ).Required to run applications of production environment ( on client host system ).

JVM is available in both JDK and JRE. Java.exe file is used to initiate VM process.The default heap size is 2MB and the Max.heap size is 64MB.VM comes in two flavours... -Hotspot client VM -Hotspot server VM

JDK: Java Developer Kit contains tools needed to develop the Java programs, and JRE to run the programs. The tools include compiler (javac.exe), Java application launcher (java.exe), Appletviewer, etc Compiler converts java code into byte code. Java application launcher opens a JRE, loads the class, and invokes its main method. You need JDK, if at all you want to write your own programs, and to compile them. For running java programs, JRE is sufficient. JRE: Java Runtime Environment contains JVM, class libraries, and other supporting files. Actually JVM runs the program, and it uses the class libraries, and other supporting files provided in JRE. If you want to run any java program, you need to have JRE installed in the system. JVM: Java Virtual Machine interprets the bytecode into the machine code depending upon the underlying operating system and hardware combination. It is responsible for all the things like garbage collection, array bounds checking, etc JVM is platform dependent. The JVM is called "virtual" because it provides a machine interface that does not depend on the underlying operating

system and machine hardware architecture. This independence from hardware and operating system is a cornerstone of the write-once run-anywhere value of Java programs.

JVM: Java Virtual Machine-It is beck-end software of java which support java program execution. Just like an Operating System (but JVM is not OS) it provides process/memory management while executing a java program. It is nbot a particular executable program. It is set of programs which gets loaded while executing a java proggram using 'java' JRE: Java Runrime Environment: It is a Java software which is used to execute a java program. JRE provides only runtime environment not a complie time environment. You can not complie a java program in your machine if you have only JRE. JAVAC: It is a program (part of JDK) used for compling a java program.

Das könnte Ihnen auch gefallen