jvm
JDK、JRE、JVM区别与联系
JVM
jvm(Java Virtual Machine),java虚拟机,java运行时的环境,是一种用于计算机设备的规范,是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
java虚拟机在执行字节码时,把字节码解释成具体平台的机器指令。
jvm实现了平台无关性,jvm屏蔽了具体操作平台的具体信息,使得java程序只需要生成在jvm上运行的字节码,就可以在不同平台上不加修改的运行,实现了一次编译多处运行。
JRE
JRE(Java Runtime Environment,Java运行环境)
包含jvm和java核心类库。是Java运行环境,
JDK
JDK(Java Development Kit) 是java开发工具包,包括了JRE。
GC
怎么定义垃圾
引用计数法
在对象中引入一个计数器,每当有一个地方引用它就加一,引用失效就减一。当引用计数器为0时就意味着是垃圾。
但是主流的虚拟机都没用选用引用计数法,因为必须要配合大量的额外处理才能够保证正确地工作,譬如简单的引用计数法就无法解决对象之间的循环引用。
可达性分析法
将GC Root作为起始节点,从这些节点开始,根据引用关系向下搜索,搜索时走过的路径称为“引用链”,若某个对象到GC Root之间没用任何引用链连接,或者用图论的话来说,从GC Root到这个对象不可达时,则证明该对象是垃圾
GCRoot:以下地方直接或间接引用的对象
- 栈:正在使用不能删除
- 本地方法栈
- 方法区:全局变量,需要保留。
GC算法
1.标记—清理法
在对象后面标记,再扫描一遍就将其删除掉。
缺点:产生内存碎片
2.标记—整理法
在清除之后,后面对象往前面顶
缺点:前移代价大
3.复制算法
将内存分为1区和2区,在1区创建对象,之后标记1区是否需要删除,在1区快满的时候将不需要删除,紧凑的复制到2区。
缺点:需要两倍的内存。
实际GC算法
将java堆分为young区和old区。
young区的垃圾回收器是ParNew垃圾回收器。按照8:1:1将young区分为eden区,以及两个servivor区,来交替工作,提高利用率。新创建的对象一般被分配到eden区,当该区满了之后就会触发一次young GC,采用复制算法,将eden区不需要删除的对象复制到servivor区。
old区,在yongGC时年龄加一,直到满了6岁,就会复制到old区。同时存一些大对象。在old GC会同时伴随young GC,所以又称full GC,full GC 会引起stop the world,整个程序暂停,采用标记-清理。标记-整理。
在正式Minor GC之前会检查young区中的对象,比old区剩余空间大还是小。假如Minor GC后survivor区放不下剩余对象,这些对象就要进入old区。
- old区剩余空间大于young区对象大小,就直接GC。就算survivor区不够放,old区还是够放的
- 小于。查看是否启用了“老年代空间分配担保规则”
- 如果老年代剩余空间大小大于历次Minor GC之后剩余对象大小,那就允许Minor GC.因为从概率上讲,以前放得下,现在也放得下。那就会产生两种情况
- 如果小于,进行full GC.
GC失败原因
- full GC 仍然放不下,只能OOM.
- 未开启老年代分配担保规则,且full GC后仍然放不下,只能OOM.
- 开启了老年代分配担保规则,但是担保不通过,只能OOM.
虚拟机堆和栈的区别
1. 功能和作用:
栈是用来执行程序的,堆是用来存放对象的
栈:栈可以看作方法的运行模型,所有方法的调用都是通过栈帧实现的,jvm会为每个线程分配一个栈,jvm只对栈进行压栈和出栈操作。当一个线程进入一个java方法函数时,就会在当前栈中压入一个栈帧保存当前线程的状态,当退出函数时,会讲该