简单来说JVM是解析和运行java程序的,JVM 运行在操作系统(windows,linux、mac)之上,与硬件没有直接的交互。
2、JVM内存模型 3、类加载器
1、作用:负责加载class文件到jvm中,只负责加载,具体能否执行有执行引擎(Execution Engine)决定
2、分为以下4种类型
1)启动类(根)加载器(Bootstarp) C++,加载jre/lib/rt.jar,
2)扩展累加载器 (Extension),加载 jre/lib/ext/*.jar;
3)应用程序加载器(appClassLoader),加载当前classpath的所有类
4)自定义加载器,
a) 继承 classloader类
b) 重写 findClass 方法或者 loadClass 方法,其中 findClass 方法不会打破双亲委 派,loadClass方法会打破双亲委派
3、.class文件由 特定标识 cafe babe 开头,所以能被classloader识别
4、加载顺序分为7步:
加载->链接(验证+准备+解析)->初始化(使用前的准备)->使用->载载
4、双亲委派机制通俗解释:当一个class文件需要加载时,不考虑自定义加载器的情况,classloader会先检查 appClassloader是否加载过,如果加载了,就不需要重复加载了,反之,会找到父加载器调用loadClass 方法,也需要先判断 是否加载过,如果加载过不重复加载,没有加载过就会继续向上查找,直到找到 BootstarpClassLoader加载器,它也是先检查是否加载,加载了就不重复加载,如果没有加载,先判断能不能加载class文件,如果能加载就加载到内存中,如果不能加载就通知子加载器去加载,一直到最底层的加载器。
好处:可以一定程度防止危险代码植入,例如有人像篡改 String.java 类,他首先会被BootStarpClassLoader加载,其他的加载器不会再去加载,所以可以一定程度避免危险代码植入。
5、jvm堆中的内存组成1、年轻代,年轻代又分为:eden,from,to 三部分,默认比例为 8:1:1,此比例可以通过 –XX:SurvivorRatio 来设定
2、老年代
3、永久代(1.8以后叫元空间)
6、GC是什么?为什么要GCGC,就是垃圾回收,帮助jvm释放内存,可以一定程度避免OOM。
7、垃圾收集算法有哪些1、标记清除,分两步,先标记,再清除,首先需要标记出所有需要回收的对象,然后进行清除回收变为可用内存,效率低,会有垃圾碎片产生
2、复制算法,将可用堆内存按照容量分为大小相等的两块,每次只用一块,当这块内存快用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存一次清理掉。年轻代from->to 就是采用此算法,效率较高、不会产生碎片,但是会浪费一部分内存
3、标记整理,分两步 标记和整理,严格来讲整理又分为两步 整理 + 清除,老年代采用标记整理算法,好处就是不会产生碎片问题,适合年老代的大对象存储,不像复制算法那样浪费空间。但是从效率上来讲不如复制算法,
8、分代垃圾回收怎么工作的新生代:把 Eden + From Survivor(S1) 存活的对象放入 To Survivor(S2) 区,然后清空Eden 和 S1,两区交换,S1变为S2,S2变为S1,轻GC
老年代:每次S1到S2的时候,年龄就会+1,直到加到15(默认值,可以通过“-XX:MaxTenuringThreshold”参数修改),就会进入老年代,大对象会直接进入老年代,当老年代的空间达到某个值就会采用标记整理算法进行垃圾回收,这个时候是全局的,重GC
9、常用的调优工具JDK命令行工具:
jps命令(查看jvm进程信息)、jstat(监视jvm运行状态的,比如gc情况、jvm内存情况、类加载情况等)、jinfo(查看jvm参数的,也可动态调整)、jmap(生成dump文件的,在dump的时候会影响线上服务)
第三方工具:JProfiler分析dump文件
10、GC常用参数-Xmn:年轻代
-Xms:最小堆
-Xmx :最大堆
-Xss:栈空间
-XX:+UseTLAB:使用TLAB,默认打开
-XX:+PrintTLAB:打印TLAB的使用情况
-XX:TLABSize:设置TLAB大小
-XX:+DisableExplictGC:禁用System.gc()不管用 ,防止FGC
-XX:+PrintGC:打印GC日志
-XX:+PrintGCDetails:打印GC详细日志信息
-XX:+PrintHeapAtGC:打印GC前后的详细堆栈信息
-XX:+PrintGCTimeStamps:打印时间戳
-XX:+PrintGCApplicationConcurrentTime:打印应用程序时间
-XX:+PrintGCApplicationStoppedTime:打印暂停时长
-XX:+PrintReferenceGC:记录回收了多少种不同引用类型的引用
-verbose:class:类加载详细过程
-XX:+PrintVMOptions:jvm参数
-XX:+PrintFlagsFinal:-XX:+PrintFlagsInitial 必须会用
-Xloggc:opt/log/gc.log:gc日志的路径以及文件名称
-XX:MaxTenuringThreshold:升代年龄,最大值15
11、系统CPU经常100%怎么排查1. 找出哪个进程cpu占用高(top命令)
2. 该进程中的哪个线程cpu占用高( top -H -p $pid 命令)
3. 将十进制的tid转化为十六进制( printf %x $tid 命令)
4. 导出该线程的堆栈 ( jstack $pid >$pid.log 命令)
5. 查找哪个方法(栈帧)消耗时间 ( less $pid.log )
6. 可以确认工作线程占比高还是垃圾回收线程占比高
7. 修改代码
12、调优思路
1、尽可能让对象在新生代里分配和回收,避兔对象频繁进入老年代导致老年代频繁垃圾回收;
2、给系统充足的内存空间,避免新生代频繁的垃圾回收;
3、指定合适的垃圾收集器



