002、一探究竟:我们写的Java代码到底是如何运行起来的?
003、面试官对于 JVM 类加载机制的猛烈炮火,你能顶住吗?
类的加载到使用:
加载-验证-准备-解析-初始化-使用-卸载
008、聊聊JVM分代模型:年轻代、老年代、永久代
package com.msb.com.sz;
/**
* @description:
* @date : 2020/8/30 15:31
* @author: zwz
*/
public class Kafka {
public static void main(String[] args) throws InterruptedException {
loadReplicasFromDisk();
while (true) {
loadReplicasFromDisk2();
Thread.sleep(1000);
}
}
/**
* 1. 执行main方法,会把main 方法的栈帧压入main线程的java虚拟机栈
* 2. 每次在while循环中调用 loadReplicasFromDisk 方法,会把 loadReplicasFromDisk 方法的栈帧压入自己的java虚拟机栈
* 3. 在执行 loadReplicasFromDisk 方式时,会在java堆中创建一个ReplicaManger对象实例
* 4. loadReplicasFromDisk 方法的栈帧中会有 replicaManger 局部变量去引用java堆内存中的 ReplicaManger对象实例
* <p>
* 5. loadReplicasFromDisk方法结束,栈帧出栈。ReplicaManger对象实例没有引用了,会被JVM的垃圾回收线程给回收掉。存活周期很短。
*/
private static void loadReplicasFromDisk() {
ReplicaManger replicaManger = new ReplicaManger();
replicaManger.load();
}
/**
* 1. 方法区的指针 replicaManger 引用了 ReplicaManger 实例
* 2. 这个实例对象会一直被Kafka的静态变量引用着,会一直驻留在java堆内存中,是不会被垃圾回收掉的。生命周期很长
*/
private static ReplicaManger fetcher = new ReplicaManger();
private static void loadReplicasFromDisk2() {
fetcher.load();
}
}
009、大厂面试题:你的对象在JVM内存中如何分配?如何流转的?
010、动手实验:亲自感受一下线上系统部署时如何设置JVM内存大小?
011、案例实战:每日百万交易的支付系统,如何设置JVM堆内存大小?
- 每天JVM内存中会频繁地创建和销毁100万个支付订单,核心问题:
- 支付系统需要部署多少机器?
- 每台机器需要多大的内存空间?
- 每台机器上启动的JVM需要多大的堆内存空间?
- 给JVM多大的内训空间才可以保证可以支撑这么多的支付订单在内存里的创建,而不会导致内存不够直接崩溃?
每s 30个订单 30*500byte=15kb
-
每秒处理多少笔订单
-
对完整的支付系统内存占用需要进行预估
每s创建出来的被栈内存的局部比那辆引用的对象大概占据内存空间就在几百KB-1MB之间。
4核8G。JVM 4G,堆空间 3G,新生代2G
012、案例实战:每日百万交易的支付系统,JVM栈内存与永久代大小又该如何设置?
-
支付系统内存设置过小,然后突然巨大的流量压力,突然的性能抖动,最后导致很多对象长期在新生代被人引用,无法被回收,最后持续进入老年代,最后触发老年代聂村都频繁占满,然后老年代都频繁被垃圾回收。
-
永久代几百个MB
-
栈512-1MB
013、第2周作业:看看你们的线上系统是如何设置JVM内存大小的?
015、大厂面试题:什么情况下JVM内存中的一个对象会被垃圾回收?
- 只要对象被方法的局部变量、类的静态变量引用,就不会回收他们。
016、大厂面试题:JVM中有哪些垃圾回收算法,每个算法各自的优劣?
017、大厂面试题:年轻代和老年代分别适合什么样的垃圾回收算法?
- 如果新生代有大量对象存活下来,确实是自己的survivor区放不下了,必须转移到老年代去。如果老年代里的空间也不够放这些对象呢?
- 在执行任何一次minor GC之前,JVM会先检查老年代可用的内存空间,是否大于新生代所有对象的总大小。
- 如果大于就可以发起 minorGC了。如果小于新生代全部对象的大小,会看 -XX:-HandlerPromotionFailture 的参数设置。
- 如果有就看老年代的内存大小,是否大于之前minor GC后进入老年代的对象的平均大小。
- 失败会触发一次Full GC。为了对老年代进行回收,腾出一些内存空间,然后执行 minor GC。
- minor GC 后可能的结果:
- 剩余的存活对象的大小小于survivor区的代下的,此时存活对象进入survivor区
- 剩余的存活对象的大小大于survivor区域的大小,但是小于老年代可用内存大小的,直接进入老年代
- 剩余的存活对象的大小大于了survivor区域的大小和老年代可用内存大小,触发FullGC
-
fullGC后还是不够,发生OOM
-
老年代垃圾回收算法:
018、大厂面试题:JVM中都有哪些常见的垃圾回收器,各自的特点是什么?
- 每台机器每分钟负责执行100次数据提取和计算任务。每次1w条数据到内存中,平均每次10s左右
- 每条数据在1kb左右大小,每次计算任务的1W条数据对应了10MB的大小。
019、“Stop the World”问题分析:JVM最让人无奈的痛点!
022、一步一图:深入揭秘JVM的年轻代垃圾回收器ParNew是如何工作的!
023、一步一图:那JVM老年代垃圾回收器CMS工作时,内部又干了些啥?
024、动手实验:线上部署系统时,如何设置垃圾回收相关参数?
025、案例实战:每日上亿请求量的电商系统,年轻代垃圾回收参数如何优化?
Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的快一点,但是也可能会导致机器暂时间变慢。
Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占用更多的内存,超出了这个设置值,就会抛出OutOfMemory异常。
Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程大约需要占用多少内存,可能会有多少线程同时运行等。
网友评论