JVM 01(essential)
- JVM JRE JDK
- JVMabstract machine:platform dependent
- JVMfunction:1 load codes;2verify codes(strictly typed)--compile error; 3excute the codes;4provide runtime environment
- runtime environment:actual implementation of JVM, JVM is in jre(physically present), jre contains libraries and other files JVM uses.
- JDK contains JRE+development tools(like javac),also physically present
class loader + runtime data areas + excution engine
- class loader{load + link + initialize}
加载.class文件(从哪里加载、classpath的设置),编译,内存分配(有默认值的变量及所有引用值(对其他class文件或常量)),初始化(static的block或var)
- load{ bootstrap class loader<- extension class loader<-application class loader,查找.class文件顺序 }
- 通常class file not found
- load from .class or .jar file which contains .class file
- loader implement不同则接收不同data source
- bootstrap class loader: load rt.jar
- extension class loader:load form jre/lib/ext folder
- application class loader:load from CLASSPATH -cp
- CLASSPATH and settings
- .class重名 ,-cp 选择在CLASSPATH中第一个出现的.class文件
- 而-Xmx设置则选择后者 java -Xmx128m -Xmx256m Hello.class
- jinfo -flag MaxHeapSize pid 查看
- link{verify + prepare +resolve}
- verify byte codes
- memory allocation for class vars to default value
- resolve: all symbolic references inside the current class(references to其他classes 或 to values constants pool)
- resolve通常产生class def not found,即class文件中所有对其他class 或methods的引用not found
- initialize
- static block
- set values for static vars(vars to initalized value)
- runtime data areas
Method + Heap + Java Stacks + PC registers +Native method Stacks
- method area
- stored metadata corresponding to class(reflectionAPI所为即访问这里的metadata数据)
- 比如static var ,constants pool等class level的data 分配给JVM的内存,-XX:MaxPermSize 默认值64MB
- Java语言并不要求常量一定只有编译期间才能产生,运行期间也可以将新的常量放入池中
- JIT编译器编译后的代码
- 内存不够 java.lang.OutOfMemoryError:PermGen space...
- !!java8 中为meta space并且没有限制 将PermGen space移到了native os的一个分开的内存
- !!栈上分配、标量替换等优化技术使得对象一定分配在堆上这件事情已经变得不那么绝对了。
- heap
- object data, 每一次new 或arrys等
- -Xms -Xmx 最小最大的内存 分配
- OutOfMemoryError
- programcounter register
- 对每个thread有一个program counter
- counter则是指向下一instruction的指针
- stack
- 每个thread 有一个stack
- 将thread的不同methods push到stack中
- 如m1 call m2那么将在m1基础上push m2到stack中,return则将m2 pop out
- 数据如 parameters , parameter array,local vars, return values, operant stack(暂存区进行操作)
- java.lang.StackOverflowError -Xss
- StackOverFlowError
- native method stack
- 如 call .dll /.so文件在本地 lib
每个JVM只有一个method area和heap,但thread级是stack,如果彼此不交互则threadsafe
- excution engine
{interpreter + JIT compiler+hostspot profiler+garbage collector}
With JVM, both interpreter and compiler (the JVM compiler and not the source-code compiler like javac) produce native code (aka Machine language code for the underlying physical CPU like x86) from byte code.
Since Java designer went for (hardware & OS) portability, they had chosen interpreter architecture (as opposed to c style compiling, assembling, and linking).
However, in order to achieve more speed up, a compiler is also optionally added to a JVM.
Nonetheless, as a program goes on being interpreted (and executed in physical CPU) "hotspot"s are detected by JVM and statistics are generated. Consequently, using statistics from interpreter, those sections become candidate for compilation (optimized native code).
It is in fact done on-the-fly (thus JIT compiler) and the compiled machine instructions are used subsequently (rather than being interpreted).
- interpreter
- directly execute bytecode without transforming it into machine code
- Just-In-Time compiler &hotsot profiler
- jit translates byte code into machine code and then execute the machine code.
- hotsot 根据interpreter行为特点的观察,发现不断地重复执行相同指令,让JIT compiler保存
- 最重要的优化策略是编译器可以决定何时从主存取值,何时向寄存器存值。但是线程的同步对于这种操作来说是至关重要的,因为一个线程无法得知另一个线程所使用的寄存器里变量的值
-
Just In Time,简称JIT,可以理解为动态编译。运行时才可以确定具体要编译的代码。还有一种,叫Ahead Of Time,简称AOT,可以理解为静态编译,即编译器在编译阶段就确定所有的运行代码
- 在运行时 JIT 会把翻译过的机器码保存起来,以备下次使用,因此从理论上来说,采用该 JIT 技术可以接近以前纯编译技术。
- GC
- clean up unused calsses objects and memory areas
- JNI java native interface (medium for java method calls for native methods . provide info about native library to JVM
- 补充
ldc:Push item from run-time constant pool,从常量池中加载指定项的引用到栈。
astore_<n>:Store reference into local variable,将引用赋值给第n个局部变量。
String baseStr = "baseStr"; //栈中有常量的引用并将此引用赋值给baseStr final String baseFinalStr = "baseStr";//同上,压栈 String str1 = "baseStr01"; String str2 = "baseStr"+"01";//同上 String str3 = baseStr + "01";
//生成一个stringBuilder实例(new dup(赋值new对象的引用并压入栈中) invokespecial(调用常量池中的第五项,即StringBuilder.<init>方法。)) //aload_1 :加载第一个参数的值,即”baseStr”
//invokevirtual #6 :调用StringBuilder对象的append方法。
//ldc #7:加载常量池中的第七项(”01″)到栈中。
//invokevirtual #6:调用StringBuilder.append方法。
//astore 5:将29中的结果引用赋值改第五个局部变量,即对变量str3的赋值。//invokevirtual #8:调用StringBuilder.toString方法。
String str4 = baseFinalStr+"01"; String str5 = new String("baseStr01").intern(); System.out.println(str1 == str2); System.out.println(str1 == str3); System.out.println(str1 == str4); System.out.println(str1 == str5);
常量池:2'baseStr' 3'baseStr0'1 4 5StringBuilder.<init>方法 6 7'01'
浙公网安备 33010602011771号