Java之JVM大纲
2022-05-06 10:56:59 43 举报
AI智能生成
Java之JVM大纲
作者其他创作
大纲/内容
描述一下jvm内存模型,以及这些空间的存放的内容
堆内存划分的空间,如何回收这些内存对象,有哪些回收算法?
1. 查看监控,以了解出现问题的时间点以及当前FGC的频率(可对比正常情况看频率是否正常)
2. 了解该时间点之前有没有程序上线、基础组件升级等情况
3. 了解JVM的参数设置,包括:堆空间各个区域的大小设置,新生代和老年代分别采用了哪些垃圾收集器,然后分析JVM参数设置是否合理。
4. 再对步骤1中列出的可能原因做排除法,其中元空间被打满、内存泄漏、代码显式调用gc方法比较容易排查。
5. 针对大对象或者长生命周期对象导致的FGC,可通过 jmap -histo 命令并结合dump堆内存文件作进一步分析,需要先定位到可疑对象。
6. 通过可疑对象定位到具体代码再次分析,这时候要结合GC原理和JVM参数设置,弄清楚可疑对象是否满足了进入到老年代的条件才能下结论。
如何解决线上gc频繁的问题
描述一下class初始化过程
内存泄漏 VS 内存溢出
java.lang.OutOfMemoryError: ......java heap space..... 堆栈溢出,代码问题的可能性极大
java.lang.OutOfMemoryError: GC over head limit exceeded 系统处于高频的GC状态,而且回收的效果依然不佳的情况,就会开始报这个错误,这种情况一般是产生了很多不可以被释放的对象,有可能是引用使用不当导致,或申请大对象导致,但是java heap space的内存溢出有可能提前不会报这个错误,也就是可能内存就直接不够导致,而不是高频GC.
java.lang.OutOfMemoryError: PermGen space jdk1.7之前才会出现的问题 ,原因是系统的代码非常多或引用的第三方包非常多、或代码中使用了大量的常量、或通过intern注入常量、或者通过动态代码加载等方法,导致常量池的膨胀
java.lang.OutOfMemoryError: Direct buffer memory 直接内存不足,因为jvm垃圾回收不会回收掉直接内存这部分的内存,所以可能原因是直接或间接使用了ByteBuffer中的allocateDirect方法的时候,而没有做clear
java.lang.StackOverflowError - Xss设置的太小了
java.lang.OutOfMemoryError: unable to create new native thread 堆外内存不足,无法为线程分配内存区域
java.lang.OutOfMemoryError: request {} byte for {}out of swap 地址空间不够
简述一下内存溢出的原因,如何排查线上问题
jvm有哪些垃圾回收器,实际中如何选择
简述一下Java类加载模型?
1、字符串存在永久代中,容易出现性能问题和内存溢出。
2、类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太大则容易导致老年代溢出。
3、永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。
1,每个加载器有专门的存储空间。
2,不会单独回收某个类。
3,元空间里的对象的位置是固定的。
4,如果发现某个加载器不再存货了,会把相关的空间整个回收。
元空间的特点
JVM8为什么要增加元空间,带来什么好处
1. G1的设计原则是\"首先收集尽可能多的垃圾(Garbage First)\"。因此,G1并不会等内存耗尽(串行、并行)或者快耗尽(CMS)的时候开始垃圾收集,而是在内部采用了启发式算法,在老年代找出具有高收集收益的分区进行收集。同时G1可以根据用户设置的暂停时间目标自动调整年轻代和总堆大小,暂停目标越短年轻代空间越小、总空间就越大;
2. G1采用内存分区(Region)的思路,将内存划分为一个个相等大小的内存分区,回收时则以分区为单位进行回收,存活的对象复制到另一个空闲分区中。由于都是以相等大小的分区为单位进行操作,因此G1天然就是一种压缩方案(局部压缩);
3. G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独立的survivor(to space)堆做复制准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运行在不同代之间前后切换;
4. G1的收集都是STW的,但年轻代和老年代的收集界限比较模糊,采用了混合(mixed)收集的方式。即每次收集既可能只收集年轻代分区(年轻代收集),也可能在收集年轻代的同时,包含部分老年代分区(混合收集),这样即使堆内存很大时,也可以限制收集范围,从而降低停顿。
5. 因为G1建立可预测的停顿时间模型,所以每一次的垃圾回收时间都可控,那么对于大堆(16G左右)的垃圾收集会有明显优势
堆G1垃圾收集器有了解么,有什么特点
介绍一下垃圾回收算法
先行发生原则(Happens-Before)是判断数据是否存在竞争、线程是否安全的主要依据。先行发生是Java内存,模型中定义的两项操作之间的偏序关系,如果操作A先行发生于操作B,那么操作A产生的影响能够被操作B观察到。
口诀:如果两个操作之间具有happen-before关系,那么前一个操作的结果就会对后面的一个操作可见。是Java内存模型中定义的两个操作之间的偏序关系。
一个线程中的每个操作,happen-before在该线程中的任意后续操作。(注解:如果只有一个线程的操作,那么前一个操作的结果肯定会对后续的操作可见。)程序顺序规则中所说的每个操作happen-before于该线程中的任意后续操作并不是说前一个操作必须要在后一个操作之前执行,而是指前一个操作的执行结果必须对后一个操作可见,如果不满足这个要求那就不允许这两个操作进行重排序
1.程序顺序规则
对一个锁的解锁,happen-before在随后对这个锁加锁。(注解:这个最常见的就是synchronized方法和syncronized块)
2.锁规则
对一个volatile域的写,happen-before在任意后续对这个volatile域的读。该规则在CurrentHashMap的读操作中不需要加锁有很好的体现
3.volatile变量规则
如果A happen-before B,且B happen-before C,那么A happen - before C.
4.传递性:
Thread对象的start()方法happen-before此线程的每一个动作。
5.线程启动规则
线程的所有操作都happen-before对此线程的终止检测,可以通过Thread.join()方法结束,Thread.isAlive()的返回值等手段检测到线程已经终止执行。
6.线程终止规则
对线程interrupt()方法的调用happen-before发生于被中断线程的代码检测到中断时事件的发生。
7.线程中断规则
常见的happen-before规则
Happens-Before规则
加载,链接(验证,准备,解析),初始化,使用,卸载
加载主要是将.class文件通过二进制字节流读入到JVM中。 在加载阶段,JVM需要完成3件事
1)通过classloader在classpath中获取XXX.class文件,将其以二进制流的形式读入内存。
2)将字节流所代表的静态存储结构转化为方法区的运行时数据结构;
3)在内存中生成一个该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
加载
主要确保加载进来的字节流符合JVM规范。验证阶段会完成以下4个阶段的检验动作
1)文件格式验证
2)元数据验证(是否符合Java语言规范)
3)字节码验证(确定程序语义合法,符合逻辑)
4)符号引用验证(确保下一步的解析能正常执行)
验证
准备是连接阶段的第二步,主要为静态变量在方法区分配内存,并设置默认初始值。
准备
解析是连接阶段的第三步,是虚拟机将常量池内的符号引用替换为直接引用的过程
解析
链接
初始化阶段是类加载过程的最后一步,主要是根据程序中的赋值语句主动为类变量赋值。当有继承关系时,先初始化父类再初始化子类,所以创建一个子类时其实内存中存在两个对象实例。
初始化
程序之间的相互调用。
使用
即销毁一个对象,一般情况下中有JVM垃圾回收器完成。代码层面的销毁只是将引用置为null。
卸载
描述一下java类加载和初始化的过程?
JVM线上出OOM问题了如何定位?
Parallel Scavenge+Parallel Old(多线程并行)
吞吐量优先
cms+par new(并发回收垃圾)
响应时间优先
吞吐量优先和响应时间优先的回收器是哪些?
ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列,线程池,生产者消费者
LinkedBlockingQueue:一个由链表结构组成的无界阻塞队列,线程池,生产者消费者
PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列,可以实现精确的定时任务
DelayQueue:一个使用优先级队列实现的无界阻塞队列,可以实现精确的定时任务
SynchronousQueue:一个不存储元素的阻塞队列,线程池
LinkedTransferQueue:一个由链表结构组成的无界阻塞队列
LinkedBlockingDeque:一个由链表结构组成的双向无界阻塞队列,可以用在“工作窃取”模式
什么叫做阻塞队列的有界和无界,实际中有用过吗
jvm监控系统是通过jmx做的么
内存屏障的汇编指令是啥
怎么提前避免内存泄漏
Java之JVM大纲
0 条评论
回复 删除
下一页