随着互联网的发展,高并发高可用、快 速响应成为软件的必须,而JVM与这些有着密切关联。之前JVM系列好多都是一些由于STW影响到快 速响应问题,忽然网站慢一下(抖动下)等问题,下面谈谈用JVM排查到的高并发高可用问题。(在高可用高并发下面问题原因可能会很多,比如cpu异常高、磁盘IO高、SWAP空间等,有可能很多问题都是综合性的问题)。
某业务线集群服务升级忽然上线上去不能提供服务,之后影响到整个集群,查看当时服务器情况,负载、cpu、io、swap等都正常,查看日志就是卡在末尾一行不动了(也没有发现OOM,等任何异常)。现在排查问题多了一个维度JVM(的确有时候需要考虑的,并且现在很多监控工具都会考虑到JVM的)。
查看gcutil查看比例,发现from 100% eden 100% old 100%但是服务就是没有OOM,执行任何都命令都非常缓慢了(更别谈访问请求了),查看具体gc日志发现concurrent mode failure 并且时间很长,猜测就是一瞬间量把内存给用完了,导致from 100% eden 100% old 100%现象,终不能提供服务,之后其他集群节点也陆续出现了此类情况,重启无效,现象一样很快就from 100% eden 100% old 100% 不能提供服务,没办法,一直重启直到都启动好了可以正常提供服务。
对于java虚拟机的问题,面试时无非就是这几点。首先,jvm加载类的机制是什么?Java中的所有类,都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类,而它的工作就是把class文件从硬盘读取到内存中。在写程序的时候,我们几乎不需要关心类的加载,因为这些都是隐式装载的,除非我们有特殊的用法,像是反射,就需要显式的加载所需要的类。 Java类的加载是动态的,它并不会一次性将所有类全部加载后再运行,而是确保程序运行的基础类(像是基类)完全加载到jvm中,至于其他类,则在需要的时候才加载。这当然就是为了节省内存开销。
委托模型机制是什么?委托模型机制的工作原理很简单:当类加载器需要加载类的时候,先请示其Parent(即上一层加载器)在其搜索路径载入,如果找不到,才在自己的搜索路径搜索该类。这样的顺序其实就是加载器层次上自顶而下的搜索,因为加载器必须确保基础类的加载。之所以是这种机制,还有一个安全上的考虑:如果某人将一个恶意的基础类加载到jvm,委托模型机制会搜索其父类加载器,显然是不可能找到的,自然就不会将该类加载进来。
相关文章