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:以上只是自己的一些小见解 如有错误 欢迎指正 !!