1,说一下 JVM 运行时数据区
JVM在执行java程序时会把内存划分为6个运行时数据区
1)程序计数器(Program Counter Register)
一块较小的内存空间,可以看做是字节码文件的型号指示器,如果线程正在执行java程序那么计数器记录的是正在执行的虚拟机字节码指令的地址
2)java虚拟机栈(Native Method Stack)
与程序计数器一样 他的线程也是私有的,它的生命周期与线程相同,虚拟机栈描述的是java方法执行的内存模型,每个方法在执行时都会创建一个栈帧用于储存局部变量表,操作数栈,动态链接,方法出口等,每个方法从调用到执行完成,就对应一个栈帧在虚拟机中的入栈到出栈的过程
3)本地方法栈(Native Method Stack)
本地方法栈和虚拟机栈非常相似,只是虚拟机栈是为虚拟机执行java方法服务,而本地方法栈则是为虚拟机使用到的Native方法服务
4)java堆(Java Heap)
java堆是被所有的线程共享的一块内存区域,在虚拟机启动的时候创建.此内存的最大目的就是存放内存实例,几乎所有的内存实例都在这里分配对象
5)元数据区(Method Area)
在JDK1.7的时候,JVM内存区域有个方法区,主要存放虚拟机加载的类信息,静态变量,常量等信息,
JDK1.8的时候移除了方法区,提出了元数据区,和java堆一样,被个个线程共享,用来储存被虚拟几加载的类信息,静态变量,常量,既编译器编译的代码等数据,方法区是JVM规范定义的一个概念,不同实现可以放在不同的地方
6)运行时常量池(Runtime Constant Pool)
运行时常量池是方法区的一部分,Class文件除了有类的版本,方法,字段,接口等描述以外,还有一项就是常量池,用于储存编译器生成的各种字面量和符号引用,这部分将在类加载后进入方法区的运行时常量池中存放
2,说一下栈堆的区别
栈内储存的是局部变量,堆内储存的是实体
栈内存的更新速度要大于堆内存,因为局部变量的生命周期很短
栈存放的变量生命周期一但结束就会被释放,而堆内存中存放的实体会被垃圾回收机制不定时回收
3,Java 会存在内存泄漏吗?请简单描述
长生命周期的对象持有短生命周期的对象引用就很有可能发生内存泄漏,尽管短生命周期对象已经不需要了,但长生命周期对象一直拿着它的引用而不能被回收,,这就是java内存泄漏发生的场景
4,Java 中都有哪些引用类型?
强引用:只要这个引用存在就不会被回收
软引用:有用但不是必须的对象,发生在内存溢出之前被回收
弱引用:有用但不是必须的,在下一次GC(垃圾回收)的时候被回收
虚引用:无法通过虚引用获得对象,用PhantomReference实现虚引用,虚引用用途是在GC
5,怎么判断对象是否可以被回收
判断对象的引用数量,每个 对象实例都有一个引用计数器,引用计数器为0的时候就可以当做垃圾收集了
6,说一下 JVM 有哪些垃圾回收算法
标记-清除:标记无用对象然后清理,效率不高无法清除垃圾碎片
复制:把内存一分为二,当一块用完的时候把还活着的对象放到另一块上,内存使用率不高
标记-整理:标记无用对象,让活着的对象往一端移动,把另外一端的边界以为的对象清理,
分代收集:按生命周期划分内存为新生代老年代,新生代基本采用复制算法,老年代基本采用标记整理
7,说一下 JVM 有哪些垃圾回收器
Serial收集器(复制算法)
ParNew收集器(复制算法)
Parallel Scavenge 收集器 (复制算法)
Serial Old 收集器 (标记-整理算法)
CMS(Concurrent Mark Sweep)收集器(标记-清除算法)
G1(Garbage First)收集器 (标记-整理算法)
8,详细介绍一下 CMS
以吞吐量为代价,来获得最短的停顿时间和垃圾回收器
9,简述 java 内存分配与回收策率以及 Minor GC 和 Major GC
1对象优先进入Eden区分配
2大对象直接进入老年代
3,长期存活的对象进入老年代
10,什么是双亲委派模型?
1,当需要加载类的时候,会优先选择这个类的加载器的父加载器去加载这个类
2,如果父加载器无法加载这个类的时候,在尝试在当前的类的加载器加载这个类