zoukankan      html  css  js  c++  java
  • jvm启动cpu和负载高分析

    我们知道,java进程在启动的时候经常会看到cpu会跑到百分之一百多,如果同一台机器有很多个java进程在同一时刻启动,每个进程cpu都是百分之一百多。为什么java启动会这么耗费CPU时间呢

    原因如下:

      主要是和jvm加载类文件有关,jvm在启动的时候会装载并连接所有除反射以外的类,而class文件是二进制的文件,需要从磁盘加载到内存然后解析,这种解析是很耗费cpu的,那么class文件越多,cpu耗费就越高,这正好解释了为什么同样输出Hello world,不同程序cpu占用率差别很大。这个推论正好也解释了之前遇到的另外一个线上项目的现象:每次启动后有大约1分钟左右系统的cpu和负载很高,过了1分钟后就恢复正常了

    那么java虚拟机都是按需加载类的,那么我的main函数里面完全没有用到任何其它类,为何还是会加载呢?

      今天针对这个问题继续查阅相关资料,发现原来所谓的“使用”,并不单单指我们通常编码所说看到的new、方法调用,而且还包括“依赖”。

    举个简单的例子

    package common;
     
    import java.util.*;
     
    public class CommonTester {
     
        public static void main(String[] args) {
            System.out.println("Hello, world......");
        }
     
        /**
         * 这个函数在main里面并没有调用,但jvm还是会加载ArrayList类,因为CommonTester内依赖了ArrayList类
         * @return
         */
        public List<String> createStringList(){
            return new ArrayList<String>(100);
        }
    }

    以上这个例子中,CommonTester类在main函数中并没有调用crateStringList方法,但因为CommonTester类依赖ArrayList类,那么在加载CommonTester的时候发现其依赖ArrayList类,就会先加载ArrayList类。

    所以,jvm最开始启动的时候肯定是先加载main函数所在的类,但是在加载这个类的时候发现依赖其它类,就会先加载其它类;加载其它类的时候也是这样处理,就像一个链式反应一样,所以基本上除了反射的类外,大部分类在jvm启动后,运行main函数前就已经加载完毕了。

    为了验证这个推论,重新做了验证:

    1)main函数所在的类注释所有其它代码,只保留main函数里面的打印语句

          验证结果:cpu占用和自己写的简单的hello world程序一样,占用率大约1%左右

    2)main函数所在的类注释所有其它代码,但保留import语句和main函数里面的打印语句

         验证结果:和上面的一样,这个也很好理解,只保留import语句,因为这些语句并没有用,编译的时候这些语句都被优化掉了

    jvm加载类的时候是多线程还是单线程 ?

      验证这个问题流程如下

        1)使用java -verbose启动程序,这样程序运行时就会打印加载的类

        2)使用strace跟踪,就可以知道哪些线程加载了类

        具体的命令为:strace -T -f -q -s 1024 -o strace.txt java -verbose .............(省略号代表具体的程序运行相关参数)
      通过查看strace输出的结果,发现如下现象:

        1)多个线程都会去加载类

        2)同一线程需要用到的类如果还没有加载,则自己会去加载,不会再委托给其它线程加载

    所以结论是jvm是通过多线程去加载类

  • 相关阅读:
    async函数
    Generator生成器
    ES6中的迭代器iterator
    Java多线程系列---“JUC锁”06之 公平锁(下)
    Java多线程系列---“JUC锁”05之 公平锁(上)
    Java多线程系列---“基础篇”14之 wait,sleep,join,yield,park,unpark,notify等通信机制对比
    Java多线程系列---“JUC锁”04之 LockSupport
    Java多线程系列---“JUC锁”03之 Condition
    Java多线程系列---“JUC锁”02之 ReentrantLock
    Java多线程系列---“JUC锁”01之 框架
  • 原文地址:https://www.cnblogs.com/qinghe123/p/12612472.html
Copyright © 2011-2022 走看看