- 什么叫lts?
LTS:长期支持
- 什么是oom?
Out Of Memory 中文的意思就是“内存用完了”
- 深入理解VM这本书(去解读)
- 什么是JPC?
人们常说的“java”社区,这是一个由业界多家技术巨头组成的社区组织,用于定义和发展java的技术规范。
- jDK和jRE?
JDK:Java Development Kit 是Java的标准开发工具包(普通用户只需要安装 JRE来运行 Java 程序。而程序开发者必须安装JDK来编译、调试程序)。它提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行环境JRE,以及常用的Java基础类库等,是整个JAVA的核心。
JRE:Java runtime environment 是运行基于Java语言编写的程序所不可缺少的运行环境,用于解释执行Java的字节码文件。
- 1995年java诞生,2004年JDK5发布,2017JDK9将会持续交付的形式和更加敏捷的研发节奏向前推进
- JDK8和JDK11是LTS版
- ZGC:垃圾收集器
垃圾回收器就是自动管理运行数据区的内存,将无用的内存占用进行清除,释放内存资源。
- G1的概念?
G1将整个堆划分为同等大小的区块,一个分区可以是年轻代(Eden、Survivor)、也可以是老年代分区;G1是基于一个分区进行垃圾收集的。
- HotSpot(官方)、JRockit、IBMJ9最主流的三款虚拟机
- 1996年Classic VM虚拟机发布(第一)
- HotSpot既继承了Sun之前两款 商用虚拟机的优点,也有许多自己新的技术优势,如它名称中的HotSpot指的就是它的热点代码探测技术
- 类加载子系统
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型。
- 运行时数据区
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
- 执行引擎
执行引擎用于执行JVM字节码指令,主要有两种方式,分别是解释执行和编译执行,区别在于解释执行是在执行时翻译成虚拟机指令执行,而编译执行是在执行之前先进行编译再执行。
解释执行启动快,执行效率低。编译执行,启动慢,执行效率高。
- 运行时数据区
包括:方法区,栈区,堆区,PC寄存器,本地方法栈
- 程序计数器记录的是下一条指令的地址,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内 存区域为“线程私有”的内存。
- Java虚拟机栈是线程私有的,他的生命周期与线程相同。
- Java虚拟机栈
- istore_1将int类型的值存入局部变量1(下标为1)
- Iconst_2将int类型的值压入栈。
- 局部变量表的定义
局部变量表是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。
- 局部变量表中第0位索引的便来你那个槽默认是用于传递方法所属对象实例引用。所以我们一般是从1开始的。
- 操作数栈也常被称为操作栈,它是一个先进后出栈。
- 动态连接
一些符号引用一部分会在类加载阶段或者第一次使用的时候就被转化为直接引用,这种转化被称为静 态解析。另外一部分将在每一次运行期间都转化为直接引用,这部分就称为动态连接。
- 方法出口(方法返回)
- 注意:计数指向的是下一个执行行号,以及局部变量表下标从1开始。
- 把数据放在堆好还是栈好?
具体要看是什么数据,要是跟着线程走(栈,就可以不用JC了)。需要共享(发到堆)
- 本地方法栈
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行 Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。 - Java堆区
Java堆是被所有线程共享的一块内存区域,,Java 世界里“几乎”所有的对象实例都在这里分配内存。
- Java堆是垃圾收集器管理的内存区域,因此它也被称作“GC堆”,这就是我们做JVM调优的重点区域部分。
- Java堆区图
- Eden和Survivor?
年轻代和两个Survivor区默认比例为8:1。
- JC?
表示:Java编译器
- JDK1.以后的堆的情况
- 什么是元数据空间?
元空间是方法区在HotSpot JVM中的实现,方法区主要用于存储类的信息、常量池、方法数据、方法代码等。
- JDK8的最大的变化是Perm(永久区)用Metaspace(元数据空间)进行替换。需要特别说明的是:Metaspace所占用的内存空间不是在虚拟机内部,而是在本地内存空间中,这也是与1.7的永 久代最大的区别所在。
- JDk默认状态下的分配情况
如果在没有指定堆内存大小时,默认初始堆内存为物理机内存的 1/64,最大堆内存为物理机内存的1/4 或 1G。(JDK8的情况下)小于1G按4分之一算。
- 为什么给Eden区设置的很大?
因为new的所有对象都在eden区
- 元数据空间会自动扩容
- 为什么要废弃1.7中的永久区?
简单来讲是为了融合JRockit VM所作出的努力,因为JRockit没有永久代,不需要配置永久代。
- 方法区(Method Area)(也叫“非堆”)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、 常量、静态变量、即时编译器编译后的代码缓存等数据。
- 对象的引用两种方式
使用句柄来访问的最大好处就是reference中存储的是稳定句柄地址,在对象被移动(垃圾收集时移动对象是 非常普遍的行为)时只会改变句柄中的实例数据指针,而reference本身不需要被修改。
使用直接指针来访问最大的好处就是速度更快,它节省了一次指针定位的时间开销。
HotSpot虚拟机采用的是指针访问方式实现。
- jvm的参数类型分为三类,分别是:
标准参数
-help
-version
-X参数 (非标准参数)
-Xint
-Xcomp
-XX参数(使用率较高)
-XX:newSize
-XX:+UseSerialGC
- jvm的标准参数
#打印帮助信息 java -help
#查看jvm版本 java -version
- 混合模式是由jvm自己决定的,这也是jvm默认的模式,也是比较推荐的模式。
- 格式:-XX:= 表示属性的值为 如:-XX:NewRatio=4 表示新生代和老年代的比值为1:4
- -Xms与-Xmx参数
-Xms与-Xmx分别是设置jvm的堆内存的初始大小和最大大小。 -Xmx2048m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为2048M。 -Xms512m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为512M。 适当的调整jvm的内存大小,可以充分利用服务器资源,让程序跑的更快。
- 如果想要查看正在运行的jvm就需要借助于jinfo命令查看。
- 查看某一参数的值,
用法:jinfo -flag <参数名> <进程id> F:\t>jinfo -flag MaxHeapSize 12076 -XX:MaxHeapSize=3221225472
- Jstat
jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下: jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
说明:
Loaded:加载class的数量
Bytes:所占用空间大小
Unloaded:未加载数量
Bytes:未加载占用空间
Time:时间
- 查看编译统计
Compiled:编译数量。
Failed:失败数量
Invalid:不可用数量
Time:时间
FailedType:失败类型
FailedMethod:失败的方法