JVM虚拟机概述(3)

Source

5.方法区


作用: 主要用来存储加载的类信息, 以及即时编译期编译后的信息, 以及运行时常量池

特点: 在jvm启动时创建,大小也是可以调整, 是线程共享,也会出现内存溢出。

5.1方法区所处于的位置:

      Java 虚拟机规范中明确说明:”尽管所有的方法区在逻辑上是属于堆的一部分,但对于 HotSpotJVM 而言,方法区还有一个别名叫做 Non-Heap(非堆),目的就是要和堆分开. 所以,方法区看做是一块独立于 java 堆的内存空间.

5.2方法区,堆,栈交互关系

方法区存储类信息(元信息)

堆中存储创建的对象

栈中存储对象引用

5.3方法区大小设置

-XX:MetaspaceSize 设置方法区的大小

windows jdk默认的大小是21MB

也可以设置为-XX:MaxMetaspaceSize 的值是-1,级没有限制. 没有限制 就可以使用计算机内存

可以将初始值设置较大一点,减少了FULL GC发生

5.4方法区的内部结构

方法区它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存,运行常量池等。运行常量池就是一张表,虚拟机指令根据这张表,找到要执行的类名、方法名、参数类型、字面量(常量)等信息,存放编译期间生成的各种字面量(常量)和符号引用。

5.5方法区的垃圾回收

在FULL GC时方法区发生垃圾回收.

主要是回收类信息, 类信息回收条件比较苛刻,满足以下3点即可:

1.在堆中,该类及其子类的对象都不存在了

2.该类的类加载器不存在了

3.该类的Class对象不存在了

也可以认为类一旦被加载就不会被卸载了.

特点总结

程序计数器,java栈,本地栈是线程私有的

程序计数器不会出现内存溢出

java栈,本地栈,堆,方法区可能会出现内存溢出

java栈,本地栈,堆,方法区大小是可以调整的

堆,方法区是线程共享的,是会出现垃圾回收的

6.本地方法接口


什么是本地方法

native关键字修饰的方法称为一个本地方法, 没有方法体.例如 hashCode();

为什么用本地方法

java语言需要与外部的环境进行交互(例如需要访问内存,硬盘,其他的硬件设备),直接访问操作系统的接口即可。 java的jvm本身开发也是在底层使用到了C语言


7.执行引擎


作用: 将加载到内存中的字节码(不是直接运行的机器码), 解释/编译为不同凭平台的机器码.

.java ---编译-->.class 在开发期间,由jdk提供的编译器(javac)进行源码编译 (前端编译)

.class(字节码)----解释/编译---> 机器码 (后端编译,在运行时,由执行引擎完成的)

解释器: 将字节码逐行解释执行, 效率低

编译器(JIT just in time 即时编译器): 将字节码编译,缓存起来,执行更高效, 不会立即使用编译器,将一些频繁执行的热点代码进行编译,并缓存到方法区中,以后执行效率提高了.

程序启动后,先使用解释器立即执行,省去了编译时间,程序运行一段时间后,对热点编译缓存,提高后续执行效率,采用的解释器和编译器结合的方案。