面试小知识-JVM

JVM

Java Virtual Machine的缩写,通过在实际的计算机上仿真模拟各种计算机功能实现的虚拟计算机,是为了屏蔽平台相关信息,在编译时产生字节码文件,从而在多种平台可以直接运行。

Java虚拟机本质上就是一个程序。

JVM五大模块:类装载器子系统、运行时数据区、执行引擎、本地方法接口和垃圾收集模块。

JVM核心一般分为五块:
类加载,java内存区域,内存溢出,性能优化和垃圾回收五块。
在这里插入图片描述

java内存区域(又叫运行时数据区)这一块主要分为线程共有和线程私有的部分,共有的是
方法区:存放类信息,常量和静态变量等
堆:青年代和老年代,可以位于物理上不连续的空间,但是逻辑上要连续。

私有的是
程序计数器:负责指向下一条运行的指令,之前看一个资料上说是共有部分,结果今天学习的时候发现是私有部分,因为多线程中,CPU不会保存每个线程的执行位置,只能由每个线程自己记录,而程序计数器就是这个作用和线程同生命期。

java虚拟栈:java方法执行的内存模型,它的生命周期与线程相同。
如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),当扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

本地方法栈:是为虚拟机使用到的Native方法服务。
直接内存:

内存溢出:五部分——堆,方法区,虚拟栈本地方法栈,直接内存,元空间。

GC:GC时,对象存活性的判断,主要有四大方法,
一是引用计数法:
给对象添加计数器,当被引用时加1,引用失效时减一,当为0时回收
优点:设计简单
缺点:无法解决循环引用的问题
二是可达性分析:
GC ROOTS共有四种,常理引用对象,静态属性引用对象,虚拟栈引用对象和JNI
在这里判断的方法是,当一个对象到达GC ROOTS时,如果没有引用链,则回收

三是引用分析
四是finalize()方法
判断是否包含finalize方法,如果不包含则为回收对象,如果包含,则判断是否已经执行,如果已经执行,则为回收对象,因为finalize方法只执行一次,如果未执行则执行。

垃圾收集算法:三大算法——
1、标记清除
2、复制,其中主要是青年代使用,eden和survivor的比例是8:1:1
3、标记清除整理:老年代的主要使用

垃圾收集器
新生代的三种收集器:
单线程:标记-复制算法,单机模式下使用较多
并行:标记-复制算法,一般配合CMS进行回收
parallel:标记-整理算法,目标是控制吞吐量,适合交互不是很多的情况

老年代的三种收集器:
CMS:最短回收停顿,使用的是标记-清楚算法,
步骤:

  1. 初始标记:标记 GC ROOT直接关联对象
  2. 并发标记:trace的过程
  3. 重新标记:修改标记过程中用户进程运行导致变化的标记
  4. 并发清除

串行OLD:单线程标记整理
是CMS的备用方案
parallelold:多线程,标记整理算法
为了替代串行OLD,配合新生代的并发收集器

G1收集器:将java堆划分为多个大小相同的region,跟踪各region内垃圾堆积的价值大小,每次根据清理时间,回收价值最大的region
在这里插入图片描述

垃圾回收过程
在这里插入图片描述

类加载

java类加载器:共有四种
启动类加载器
扩展类加载器
应用程序类加载器
自定义类加载器

类的生命周期
加载->连接->初始化->使用->卸载
加载:一、通过类的全限定名获取定义此类的二进制字节流
二、将二进制字节流代表的静态数据结构转化为方法区运行时数据结构
三、在内存中生成一个java.lang.Class对象,作为该类各种数据在方法区的入口
连接:分为三小步——验证,准备和解析
验证:文件名文件格式验证,字节流验证,元数据验证和符号引用验证
准备:为类变量分配内存和初始值
解析:将符号引用替换为直接引用

在这里插入一个符号引用的解释

在这里插入图片描述

四大GC

Young GC:新生代内存的垃圾收集事件称为 Young GC(又称 Minor GC),会暂停所有应用 线程,引起全线停顿,但时间越少于oldGC
在这里插入图片描述

java内存模型

在这里插入图片描述

最后提出一个问题,青年代和老年代GC有什么区别呢?(这个问题让我直接跪了阿里)

补充

JVM内存模型

笔试遇到了,
在这里插入图片描述
-Xms 理解为初始堆或者最小堆的内存大小
-Xmx 最大堆的内存大小
-Xmn 新生代的内存大小

-Xss 每个线程使用的内存大小

方法区的内存大小:
-XX:PermSize 设置非堆内存初始值,默认是物理内存的 1/64;
-XX:MaxPermSize 设置最大非堆内存的大小,默认是物理内存的 1/4;

-XX:SurvivorRatio,设置年轻代中 Eden 区与 Survivor 区的比值。

(这块我在填空题和选择题遇到过)
如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
方法区位于堆栈之间,又叫非堆,Java虚拟机规范对这个区域的限制非常宽松,除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。
如果非要实现GC,则是针对常量池的回收和对类型的卸载。

根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

方法区有时被称为持久代(PermGen)。

四种引用

强引用:类似于int i = 1;,是实例化的对象
JVM不会回收,只会报异常,值为null才会回收

软引用:软引用可用来实现内存敏感的高速缓存,比如网页缓存、图片缓存等。使用软引用能防止内存泄露,增强程序的健壮性。
SoftReference的特点是它的一个实例保存对一个Java对象的软引用, 该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。
也就是说,一旦SoftReference保存了对一个Java对象的软引用后,在垃圾线程对 这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。
另外,一旦垃圾线程回收该Java对象之 后,get()方法将返回null。
内存不足时回收

弱引用:无论如何都会回收

虚引用:如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

JVM性能调优

在这里插入图片描述
大部分和GC有关,其中包括方法区GC频繁,虽然不懂这是什么玩意

调优时参考数据

在这里插入图片描述

调优策略

一、通常-Xms和-Xmx设置相同,原因是不用去动态调整堆大小

二、将新生代的大小调大(本来一般新生代和老年代是1:2)

三、避免创建过大的对象或数组,避免加载大量数据

四、线程数合理

五、对象使用完及时null,方便回收

六、使用软引用和弱引用

七、调整一个连接的等待时间

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值