栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JVM理解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JVM理解

1、什么是JVM?

         简单来说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是什么?为什么要GC

        GC,就是垃圾回收,帮助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、指定合适的垃圾收集器

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/301209.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号