现在接手的 java 应用,启动要 3+分钟,加载 9000+个类,给虚拟机分配 20+G 的内存才够用。
我在想有没有什么方法能优化的,比如提升重启速度,或者减少所需内存。
用了 arthas 和 jconsole 一通乱看,分析不出所以然来。有啥好的分析方法或思路,能找到优化的突破口么?
1
mazyi 2021-05-29 10:39:32 +08:00
先从启动日志看起
|
2
FanError 2021-05-29 10:40:00 +08:00
试试是不是这个引起的呀
-Djava.security.egd=file:/dev/./urandom 搜 tomcat 随机数 启动慢 |
3
546L5LiK6ZOt 2021-05-29 11:48:53 +08:00 via Android
用 visualvm 看启动时哪些方法耗时最长
|
6
x97bgt OP @546L5LiK6ZOt visualvm 可以自动列出启动时所运行的方法和时间吗?我用 arthas,需要你自己给出方法的签名。
|
7
liudaolunhuibl 2021-05-29 12:00:20 +08:00 1
看下代码,根据我之前的经验这种项目会在 spring 的 bean 加载的时候做很多骚操作,比如请求某服务获取数据然后加载到内存中来,甚至查数据库。
|
8
fantastM 2021-05-29 12:32:03 +08:00
我记得 arthas 支持 profiler,还可以生成火焰图(不过我没用过
|
9
Vegetable 2021-05-29 12:34:34 +08:00
像极了从数据库读几个 G 的数据到内存
|
10
opengps 2021-05-29 12:43:33 +08:00
20+G ? 这个规模的数据集光从硬盘加载到内存就几乎占据了你全部的启动时间,想要快那恐怕先考虑换更快的硬盘吧
|
11
micean 2021-05-29 15:48:14 +08:00
指定 spring 加载的 package 范围试试?先把根源找出来
|
15
x97bgt OP @liudaolunhuibl
@Vegetable @opengps @fantastM @wanacry 有啥办法可以看到 JVM 所占用内存的使用情况和分布吗?比如,可以具体到看某个类的字节码和实例的占用内存大小。 |
16
beitayongguo 2021-05-30 00:45:32 +08:00
还是优先分析启动日志吧。可以开下 debug 日志。比如连接某些中间件一直卡在那?比如启动时 bean 做了大量 depends on ? 如果从日志分析不出啥,是不是可以考虑拆些子模块到其他应用做做瘦身?
|
17
vitoliu 2021-05-30 00:54:37 +08:00
启动慢的问题可以用 jprofile 监视一下问题出在哪儿,heapdump 快照看看
|
18
opengps 2021-05-30 10:12:33 +08:00
@x97bgt
14# 程序读取数据跟硬盘里拷贝大文件性质并不一致,所以几乎必然达不到硬盘的最高速度。粗略估算的话可以把速度减半来理解 15# 确实很多初始化的变量本身也占用较多内存,尤其是那些大量的集合,再加上这么多类库初始化的时候,很有可能很多类库都存在变量从硬盘取数赋值等小块读取硬盘的情况,会让程序的加载速度更慢,硬盘速度在这个情境下就要进一步打折了。这还不含首次启动时候 sdk 本身的调用 |
19
e583409 2021-05-30 10:38:10 +08:00
这是一道很好的面试题 哈哈
|
20
liudaolunhuibl 2021-05-30 14:09:10 +08:00
@x97bgt 好像 dump 堆栈日志可以看到,但是启动慢和你堆分布有什么关系,你现在是想解决启动慢还是堆过大
|
21
luozic 2021-05-30 14:39:36 +08:00
20Gn 内存,这加载的数据,构建的对象也太多了吧。 启动中间有 gc 没有? jprofile heapdump 如果是使用的是 openjdk 11 以上的,可以打开 flight,通过 jmc 查看事件日志。在 jdk 8 这是一个商业特性,龟壳买的 JRockit 移植到 hostspot 。。。
|
22
luozic 2021-05-30 14:42:25 +08:00
@luozic 搜到的一个介绍 java flight recorder 的介绍 blog https://cs.xieyonghui.com/java/java-flight-recorder_72.html
|
23
assiadamo 2021-05-31 12:03:17 +08:00
9000 个类不算多的,但估计是启动中有 gc 了,在启动参数中添加 gc 日志,具体看问题在哪
|
24
blessingsi 2021-05-31 12:44:17 +08:00
这种项目具体哪部分耗时,维护者心里应该有点数吧。启动的时候加载了大量数据,依赖了外部的 xxx 资源之类的。
另外就是看下 gc,分配 20g 内存大概率是会触发 gc 的。 |