V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
x97bgt
V2EX  ›  Java

Java 应用启动很慢,咋分析和优化?

  •  
  •   x97bgt · 194 天前 · 2847 次点击
    这是一个创建于 194 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在接手的 java 应用,启动要 3+分钟,加载 9000+个类,给虚拟机分配 20+G 的内存才够用。

    我在想有没有什么方法能优化的,比如提升重启速度,或者减少所需内存。

    用了 arthas 和 jconsole 一通乱看,分析不出所以然来。有啥好的分析方法或思路,能找到优化的突破口么?

    24 条回复    2021-05-31 12:44:17 +08:00
    mazyi
        1
    mazyi  
       194 天前
    先从启动日志看起
    FanError
        2
    FanError  
       194 天前
    试试是不是这个引起的呀
    -Djava.security.egd=file:/dev/./urandom

    搜 tomcat 随机数 启动慢
    546L5LiK6ZOt
        3
    546L5LiK6ZOt  
       194 天前 via Android
    用 visualvm 看启动时哪些方法耗时最长
    x97bgt
        4
    x97bgt  
    OP
       194 天前 via iPhone
    @mazyi 你的意思是,从 log 里分析,哪部分花的时间长?这个比较依赖 log 吧??
    x97bgt
        5
    x97bgt  
    OP
       194 天前 via iPhone
    @FanError 我们用的 jetty 。。。
    x97bgt
        6
    x97bgt  
    OP
       194 天前 via iPhone
    @546L5LiK6ZOt visualvm 可以自动列出启动时所运行的方法和时间吗?我用 arthas,需要你自己给出方法的签名。
    liudaolunhuibl
        7
    liudaolunhuibl  
       194 天前   ❤️ 1
    看下代码,根据我之前的经验这种项目会在 spring 的 bean 加载的时候做很多骚操作,比如请求某服务获取数据然后加载到内存中来,甚至查数据库。
    fantastM
        8
    fantastM  
       194 天前
    我记得 arthas 支持 profiler,还可以生成火焰图(不过我没用过
    Vegetable
        9
    Vegetable  
       194 天前
    像极了从数据库读几个 G 的数据到内存
    opengps
        10
    opengps  
       194 天前
    20+G ? 这个规模的数据集光从硬盘加载到内存就几乎占据了你全部的启动时间,想要快那恐怕先考虑换更快的硬盘吧
    micean
        11
    micean  
       194 天前
    指定 spring 加载的 package 范围试试?先把根源找出来
    wanacry
        12
    wanacry  
       193 天前 via iPhone
    @opengps 3g 每秒的固态 20g 也就几秒啊
    x97bgt
        13
    x97bgt  
    OP
       193 天前 via iPhone
    @fantastM 有火焰图,但好像就是一个纵览。看了不知道咋分析。。。
    x97bgt
        14
    x97bgt  
    OP
       193 天前 via iPhone
    @opengps 20 个 G 内存应该不是全用来存放加载的数据吧,但我不大懂瓶颈在哪。。。
    x97bgt
        15
    x97bgt  
    OP
       193 天前 via iPhone
    @liudaolunhuibl
    @Vegetable
    @opengps
    @fantastM
    @wanacry
    有啥办法可以看到 JVM 所占用内存的使用情况和分布吗?比如,可以具体到看某个类的字节码和实例的占用内存大小。
    beitayongguo
        16
    beitayongguo  
       193 天前
    还是优先分析启动日志吧。可以开下 debug 日志。比如连接某些中间件一直卡在那?比如启动时 bean 做了大量 depends on ? 如果从日志分析不出啥,是不是可以考虑拆些子模块到其他应用做做瘦身?
    vitoliu
        17
    vitoliu  
       193 天前
    启动慢的问题可以用 jprofile 监视一下问题出在哪儿,heapdump 快照看看
    opengps
        18
    opengps  
       193 天前
    @x97bgt
    14# 程序读取数据跟硬盘里拷贝大文件性质并不一致,所以几乎必然达不到硬盘的最高速度。粗略估算的话可以把速度减半来理解
    15# 确实很多初始化的变量本身也占用较多内存,尤其是那些大量的集合,再加上这么多类库初始化的时候,很有可能很多类库都存在变量从硬盘取数赋值等小块读取硬盘的情况,会让程序的加载速度更慢,硬盘速度在这个情境下就要进一步打折了。这还不含首次启动时候 sdk 本身的调用
    e583409
        19
    e583409  
       193 天前
    这是一道很好的面试题 哈哈
    liudaolunhuibl
        20
    liudaolunhuibl  
       193 天前
    @x97bgt 好像 dump 堆栈日志可以看到,但是启动慢和你堆分布有什么关系,你现在是想解决启动慢还是堆过大
    luozic
        21
    luozic  
       193 天前
    20Gn 内存,这加载的数据,构建的对象也太多了吧。 启动中间有 gc 没有? jprofile heapdump 如果是使用的是 openjdk 11 以上的,可以打开 flight,通过 jmc 查看事件日志。在 jdk 8 这是一个商业特性,龟壳买的 JRockit 移植到 hostspot 。。。
    luozic
        22
    luozic  
       193 天前
    @luozic 搜到的一个介绍 java flight recorder 的介绍 blog https://cs.xieyonghui.com/java/java-flight-recorder_72.html
    assiadamo
        23
    assiadamo  
       192 天前
    9000 个类不算多的,但估计是启动中有 gc 了,在启动参数中添加 gc 日志,具体看问题在哪
    blessingsi
        24
    blessingsi  
       192 天前
    这种项目具体哪部分耗时,维护者心里应该有点数吧。启动的时候加载了大量数据,依赖了外部的 xxx 资源之类的。
    另外就是看下 gc,分配 20g 内存大概率是会触发 gc 的。
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3799 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 08:35 · PVG 16:35 · LAX 00:35 · JFK 03:35
    ♥ Do have faith in what you're doing.