案例一: 写一个使用sshj包远程链接虚拟机进行操作的过程。
现象:虚拟机环境,真实主机,ide上面测试都没有出现问题,推送到了流水线发布之后运行一段时间程序变得异常缓慢,流水线环境是docker。
(整个排查过程异常麻烦,因为是给华为云做的是没有测试环境的权限的,需要跟测试人员配合想起来就是眼泪。)
排查办法:jps 获取所有java进程。 装了jdk就有这个工具。
jstack pid | grep -A 20 -B 20 “你的包名” 你可以得到运行环境中所有线程的栈信息,找到挂起线程可以查出问题所在,就可以定位问题了。 grep -A 是向下展示多少行有的组件写的狗的话20行不一定能看出来,可以根据实际情况具体调整。 -B是向上。
出现问题原因: 因为docker 或者jdk 版本的问题,导致使用节点/dev/random 获取随机数出现争抢排队的问题,最后重新换了一种随机数获取方式,没有去关心到底是docker的问题还是jdk。 预计把/dev/random 挂到docker里面区也能解决问题。
案例二: 一般来说spring托管之后不容易出现内存泄漏问题,但是毕竟需求千千万还是有可能出现,很久以前的一个工程常常用一段实践就挂掉,最后时间紧挂进程守护上的线。(只能说单子大那些年。)
排查方法: jmap -histo pid | grep “你自己的包名” (无数打脸瞬间告诉我,一定要确定是自己的问题。不然打脸很尴尬。)
以上两个方法基本可以解决开发过程中的所有问题,但是他只能解决出现的问题,并不能再程序一定的情况下改善程序运行效率。
实际应用部署的手,内存设置当然越大越好,现在jdk都是动态内存不存在浪费的说法,说你强用某个垃圾收集方法会有些会对使用效率有影响。
每个程序都有它适合jit的编译阈值,他的作用是在逃逸分析的时候让你占用使用更少的堆内存,这样也降低了栈内存到的引用到堆内存寻址,
通过这个参数进行控制 -XX:CompileThreshold 观察堆内存你自己写的实体内存数量,同一业务并发执行那个少一点。
大概就这些方法了,选gc模式什么的个人觉得有点玄学,不过改改不要stop full world 参数可以让你的程序启动快一点,但是某个内存状态下业务跑的不是特别顺(波动很小,存在理论上的,从没有注意过所以也就不具体些,就是小点一下。)
来源:CSDN
作者:王十八
链接:https://blog.csdn.net/weixin_40669549/article/details/104536114