面试题 常问之JVM ,以及在项目中如何调优

本文详细阐述了JVM中的内存结构,包括线程共享区(方法区和堆)、线程私有区(虚拟机栈、本地方法栈和程序计数器),以及新生代和老生代的堆内存管理。同时介绍了JMM的Happens-Before规则确保线程可见性。还讨论了在项目中如何处理内存不足问题,以及如何调整IDEA项目的默认内存配置。
摘要由CSDN通过智能技术生成

1.JVM中虚拟机内存结构划分

线程共享区:方法区、堆

线程私有区:虚拟机栈、本地方法栈、程序计数器

堆、方法区、虚拟机栈、本地方法栈、程序计数器。

堆内存分成新生代和老生代(大小比例1:2),新生代中由Eden和Survivor0,Survivor1组成,三者的比例是8:1:1,新生代的回收机制采用复制算法,在Minor GC的时候,我们都留一个存活区用来存放存活的对象,真正进行的区域是Eden+其中一个存活区,当我们的对象时长超过一定年龄时(默认15,可以通过参数设置),将会把对象放入老生代,当然大的对象会直接进入老生代,老生代采用的回收算法是标记整理算法

方法区(Method Area)与Java堆一样,是各线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

虚拟机栈的作用:主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native 方法服务。

分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

2.JVM的内存模型JMM

Java 内存模型(下文简称 JMM)就是在底层处理器内存模型的基础上,定义自己的多线程语义。它明确指定了一组排序规则,来保证线程间的可见性。

这一组规则被称为 Happens-Before, JMM 规定,要想保证 B 操作能够看到 A 操作的结果(无论它们是否在同一个线程),那么 A 和 B 之间必须满足 Happens-Before 关系

3.在项目中哪里用到了 在拉取项目的时候 可能会出现内存不足

 需要我们去调整idea项目中内存的大小 一般默认的值可能是

 

4.被引用的对象就一定能存活吗?

不一定,看 Reference 类型,弱引用在 GC 时会被回收,软引用在内存不足的时候,即 OOM 前会被回收,但如果没有在 Reference Chain 中的对象就一定会被回收。

5.强引用 软引用 弱引用 虚引用是什么,有什么区别

强引用,就是普通的对象引用关系,如 String s = new String("ConstXiong")

软引用,用于维护一些可有可无的对象。只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。SoftReference 实现

弱引用,相比软引用来说,要更加无用一些,它拥有更短的生命周期,当 JVM 进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。WeakReference 实现

虚引用是一种形同虚设的引用,在现实场景中用的不是很多,它主要用来跟踪对象被垃圾回收的活动。PhantomReference 实现

6.你做过JVM调优 说说如何查看 JVM 参数默认值?

jps -v 可以查看 jvm 进程显示指定的参数

使用 -XX:+PrintFlagsFinal 可以看到 JVM 所有参数的值

jinfo 可以实时查看和调整虚拟机各项参数

7.工作中常用的 JVM 配置参数有哪些?

日志 -XX:+PrintFlagsFinal,打印JVM所有参数的值

-XX:+PrintGC,打印GC信息

-XX:+PrintGCDetails,打印GC详细信息

-XX:+PrintGCTimeStamps,打印GC的时间戳

-Xloggc:filename,设置GC log文件的位置 -XX:+PrintTenuringDistribution,查看熬过收集后剩余对象的年龄分布信息

内存设置 -Xms,设置堆的初始化内存大小 -Xmx,设置堆的最大内存 -Xmn,设置新生代内存大小 -Xss,设置线程栈大小 -XX:NewRatio,新生代与老年代比值 -XX:SurvivorRatio,新生代中Eden区与两个Survivor区的比值,默认为8,即Eden:Survivor:Survivor=8:1:1 -XX:MaxTenuringThreshold,从年轻代到老年代,最大晋升年龄。CMS 下默认为 6,G1 下默认为 15 -XX:MetaspaceSize,设置元空间的大小,第一次超过将触发 GC -XX:MaxMetaspaceSize,元空间最大值 -XX:MaxDirectMemorySize,用于设置直接内存的最大值,限制通过 DirectByteBuffer 申请的内存 -XX:ReservedCodeCacheSize,用于设置 JIT 编译后的代码存放区大小,如果观察到这个值有限制,可以适当调大,一般够用即可

设置垃圾收集相关 -XX:+UseSerialGC,设置串行收集器 -XX:+UseParallelGC,设置并行收集器 -XX:+UseConcMarkSweepGC,使用CMS收集器 -XX:ParallelGCThreads,设置Parallel GC的线程数 -XX:MaxGCPauseMillis,GC最大暂停时间 ms -XX:+UseG1GC,使用G1垃圾收集器

8.什么情况发生栈溢出?

-Xss可以设置线程栈的大小,当线程方法递归调用层次太深或者栈帧中的局部变量过多时,会出现栈溢出错误 java.lang.StackOverflowError

9.使用哪些手段排查OOM问题

增加两个参数 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof,当 OOM 发生时自动 dump 堆内存信息到指定目录

同时 jstat 查看监控 JVM 的内存和 GC 情况,先观察问题大概出在什么区域

使用 MAT 工具载入到 dump 文件,分析大对象的占用情况,比如 HashMap 做缓存未清理,时间长了就会内存溢出,可以把改为弱引用 

PS:以上只是自己的一些小见解 如有错误 欢迎指正 !! 

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值