JVM相关基础知识

 

一,JVM:

当输入 java -version
java version “1.8.0_151”
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

 

(相关JVM的类型设置在jvm.cfg中设置,但是64位的JVM只支持server)

第三行的输出中可以看到:

JVM的名字(HotSpot)、类型(Client)和build ID(24.51-b03) 。

 

除此之外,我们还知道JVM以混合模式(mixed mode)在运行,这是HotSpot默认的运行模式,意味着JVM在运行时可以动态的把字节码编译为本地代码。

我们也可以看到类数据共享(class data sharing)是开启(即第三行最后的sharing)的。类数据共享(class data sharing)是一种在只读缓存(在jsa文件中,”Java Shared Archive”)中存储JRE的系统类.

 

类型一般分成两个不同的JVM编译器:

Client JVM适合需要快速启动和较小内存空间的应用,它适合交互性的应用,比如GUI;

而Server JVM则是看重执行效率的应用的最佳选择。

不同之处包括:编译策略、默认堆大小、内嵌策略。

 

2,JVM内部结构:

1.程序计数器:

 

字节码解释器会通过对这个计数器的值的改变,以完成对下一条指令的选择,

如果线程正在执行的是一个Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;

如果正在执行的是Natvie 方法,这个计数器值则为空(Undefined)

 

2.Java虚拟机栈:

虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame ①)用于存储局部变量表操作栈动态链接方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程

StackOverflowError异常   OutOfMemoryError 异常

 

3.本地方法栈(Native Method Stacks:

虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用的Native方法服务的。

 

4.Java堆(java Heap

存放对象实例,几乎所有的对象实例都在这里分配内存,Java 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可

内存管理

对象和数组永远不会显式回收,而是由垃圾回收器自动回收。通常,过程是这样的:

新的对象和数组被创建并放入老年代。

Minor垃圾回收将发生在新生代。依旧存活的对象将从 eden 区移到 survivor 区。

Major垃圾回收一般会导致应用进程暂停,它将在三个区内移动对象。仍然存活的对象将被从新生代移动到老年代。

每次进行老年代回收时也会进行永久代回收。它们之中任何一个变满时,都会进行回收。

 

垃圾收集算法

 Mark-Sweep(标记-清除)算法—>两块内存

Copying(复制)算法

Mark-Compact(标记-整理)算法—>一块内存

 

Generational Collection(分代收集)算法

一般情况下将堆区划分为老年代(Tenured Generation)和新生代(Young Generation),老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。

 

新生代:(copy)存放新生成的对象,一般分成三块,一块eden,两块儿survivor,每次把一块eden和一块survivor存活的对象(也就是无引用的对象)copy到另一块而survior中,然后把那两块的内存清理

老年代: 在年轻代中经历了N次垃圾回收后仍然存活的对象,每次回收都只回收少量对象,一般使用的是Mark-Compact算法

持久带:用来存储class类、常量、方法描述等。对永久代的回收主要回收两部分内容:废弃常量和无用的类。

 

方法区(Method Area——又名Non-Heap

方法区与Java堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息常量静态变量即时编译器编译后的代码等数据

 

5.本地方法库

动态链接库,即DLL文件,,放置于系统中

6.本地方法接口(JNI)

一个可以使java使用本地方法(native修饰的方法)的编程框架

7.执行引擎

编译执行java代码,使其编译成class文件,负责执行被加载类 中包含的指令。

Java虚拟机中的类加载器分为两种:原始类加载器(primordial class loader)和类加载器对象(class loader objects), 原始类加载器是Java虚拟机实现的一部分类加载器对象(classloader的子类)是运行中的程序的一部分

Java有四个类加载器:

Bootstrap ClassLoader:JVM开始运行的时候加载java的核心类

ExtensionClassLoader:用来加载扩展类,即/lib/ext中的类。

AppClassLoader:加载classpath中的类

URLClassLoader:加载网上的一些类

 

You may also like...