JVM相关题目
数值的整数次方
http://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00
1.结构
程序计数器 记录当前线程运行情况,当前执行位置、代码流程控制
虚拟机栈,栈帧组成,栈帧中有局部变量、动态链接(指向常量池)、方法出口、操作数栈等
本地方法栈 底层调用的方法 用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息
堆 new的对象,gc区 新生代老年带
方法区(元空间)加载完的类,常量,静态变量 对方法区进行垃圾回收的主要目标是对常量池的回收和对类的卸载。(永久代是其实现,现在叫元空间)
直接内存 直接内存不是虚拟机运行时数据区的一部分,但是这部分内存也被频繁地使用。而且也可能导致 OutOfMemoryError 错误出现。 直接内存的读写操作比堆内存快,可以提升程序I/O操作的性能。通常在I/O通信过程中,会存在堆内内存到堆外内存的数据拷贝操作,对于需要频繁进行内存间数据拷贝且生命周期较短的暂存数据,都建议存储到直接内存。
运行时常量池 在方法区中,但字符串常量池现在在堆中(String.intern() JDK6:复制 JDK7:引用地址复制一份到字符串常量池中)
问题:对象全在堆上吗?不一定,不逃逸的可以在栈上
2.类加载过程?类文件结构
类文件结构:魔数、文件版本、常量池(字面量和符号引用)、访问标志、当前类的索引
类加载过程:
类的加载指的是将类的class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内
加载、验证、准备、解析、初始化
1.加载 根据类的全限定名加载相应的类的二进制字节流,将该类的二进制字节流的静态数据结构转化为方法区中运行的数据结构,同时创建该类的class对象,作为访问入口
2.验证 为了防止格式不正确对虚拟机产生损害 主要包括一下几个验证:文件格式验证,元数据验证,字节码验证,符号引用验证
3准备 给类变量(仅包括类变量 static)准备存储空间以及相应的初始化
4.解析 将常量池中的符号引用转化为直接引用
5 初始化,调用构造方法
6.卸载,卸载的三个条件
3.双亲委派机制,类加载器
为什么用双亲委派? 自定义类加载器通过继承 classloader实现 想打破双亲委派机制重写loadclass()方法
3.对象创建过程
对象创建过程1.类加载检查 2分配内存 3初始化 4设置对象头 5代码初始化(构造函数)
(类的实例化过程) 1.首先实例化static(父类,当前类)代码块
2.父类普通代码块
3.父类的构造函数
4.当前类普通代码块
5 当前类构造函数
4.对象是否存活? GC root有哪些?四个引用的区别?mingc和fullgc
4.mingc与fullgc触发条件
MinorGC: 伊甸园区满的时候
FullGC 1.手动执行 2.老年代空间不足 3. 空间担保机制失败 4.1. 7之前永久代空间不足(未使用CMS的情况下)
4.JVM调优?
常见命令: jsp 看进程号
jstack 看线程的堆栈信息
jstat 看虚拟机运行状态(类装载,垃圾回收过程等)
jmap 堆内存快照
5.java对象定位方式 句柄和直接指针,通过栈上的reference数据来找,hotspot默认是直接指针
对象头组成 markword 指向类信息的指针 数组长度(数组才有)
GC过程?fullGC过程? 因为不论是老年代满了还是永久代满了都会触发Full GC,造成STW
OOM如何解决? 根据dump文件
垃圾回收 吞吐量 = 运行用户程序时间/(运行用户时间+垃圾回收时间)
Parallel Scavenge吞吐量优先,cms用户体验优先
cms详解
cms标记清理过程 1.初始标记 stw 记录与root相连的对象
2.并发标记,可达性分析,不需要stw
3.再次标记 stw但时间短,标记在此期间与root相连的对象
4.清除
优缺点:快,stw时间短 会有碎片,而且不能清除干净
三色标记法: 黑色、不能被回收 灰色、还存在至少一个引用没扫描 白色、可以回收 通过内存屏障、增量更新来防止错误标记
G1详解
将堆分区,物理上没有新生代老年代之分,逻辑上有。
Humongous用来存储大数据(超过region的一半)
对需要GC的region需要时间进行排序,每次根据停顿时间进行选择(停顿时间可预测)
步骤:标记,并发,再标记 回收
remenberset() 用来保存别的region的对象对这个region的对象的引用, card table 内存屏障(注意与JMM内存屏障的区别)