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

果然吃内存,一个简单的 Java 程序就占用了 250M 内存

  •  
  •   karottc ·
    karottc · 2024-07-08 20:36:54 +08:00 · 21002 次点击
    这是一个创建于 421 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前一直在用 Java 写 企业级代码,并没有很在意 java 的内存问题,比如多个/少个一两百兆就没关心。

    平时用 java 写的直接运行就结束的代码,基本都是本地电脑运行,也没有发现内存问题。

    直到最近,用 java 写了一个简单的程序,运行在我的 1C1G 的腾讯云机器上,才发现 java 确实内存大户。

    程序的功能为:

    1. 每 10 分钟抓取某个链接的数据
    2. 抓取到的内容和 mysql 里面已有的内容作对比
    3. 存在就更新,不存在就插入到 mysql 中
    4. 每天早上 10 点发送一个企业微信通知

    这就是这个程序的所有功能,由于用到了定时任务和操作 mysql, 所以我第一个版直接用了 springboot ,平时工作也用整起来快。 用到的库为:okhttp + gson + mybaits + jdbc + logback

    程序运行稳定之后内存占用:250M

    这个简单的功能这个内存占用实在是太大了。

    然后我觉得可能是 springboot 的原因,所以我写了第二版: 用了 okhttp + gson + mybatis + jdbc 去掉了框架和 logback, 直接用 print 输出 log , 定时任务也直接用了 while(true) + sleep 来实现。

    这版程序稳定运行之后内存占用:90M

    上面两版没有加任何优化参数,就是 java -jar xxx.jar 运行。 java 版本:java21


    java21 了,还是这个内存表现,失望啊。

    第 1 条附言  ·  2024-07-16 14:14:05 +08:00

    我用python 写了核心功能,内存占用 20M。

    又用quarkus-graalvm 完全1:1重构了一遍,内存占用50M。 详见这个帖子 https://www.v2ex.com/t/1057699

    125 条回复    2024-07-14 13:14:48 +08:00
    1  2  
    diagnostics
        101
    diagnostics  
       2024-07-10 08:50:42 +08:00   ❤️ 1
    @mark2025 你是觉得 chrome 不占内存吗?
    wuyiccc
        102
    wuyiccc  
       2024-07-10 10:03:17 +08:00
    java 是这样的,垃圾语言,我已经换 go 了
    baoshijiagong
        103
    baoshijiagong  
       2024-07-10 11:06:06 +08:00
    小内存机器打开 swap ,程序就不会那么容易 oom 了。写程序的关注点要注意好,java 的关注点本来就不是内存。内存贵还是时间贵。
    likeman
        104
    likeman  
       2024-07-10 12:23:21 +08:00 via Android
    如果功能就是楼主这种简单需求的话,可以试试 nodejs
    Dream95
        105
    Dream95  
       2024-07-10 13:12:32 +08:00
    爆点太多,以至于我都不知道该如何吐槽了
    NikoXu
        106
    NikoXu  
       2024-07-10 13:59:18 +08:00
    shell 就能搞定吧 , 搞什么 java
    YassoWithSpeaker
        107
    YassoWithSpeaker  
       2024-07-10 17:36:15 +08:00
    @cheng6563 看了真的很多人都不知道,jvm 启动默认 1/4 内存,这个建议百度下,很多人都说 java 占内存,spring 占内存,那 JavaME 还能跑在诺基亚上,咋不提占内存。
    cheng6563
        108
    cheng6563  
       2024-07-10 17:52:50 +08:00
    @YassoWithSpeaker 就不是这个问题,假如你 jvm 稳定运行时占 1g 内存,这时你设置 Xmx2g 和 Xmx4g 没有啥区别。

    问题是为啥没几个负载没多少功能的 Java 程序为什么要那么多内存,难道每个程序都要进行压测仔细分析负载然后配一个恰到好处的 Xmx 吗。
    JavaME 不占内存,ART 不占内存,openj9 也不占内存,为啥就 Hostpot 占内存呢。
    cheng6563
        109
    cheng6563  
       2024-07-10 18:01:21 +08:00
    @diagnostics 有一说一 Chrome 绝对比 Hostpot 要省内存,要是 Chrome 用 Java 重写,每个标签页都一个进程,那内存占用是不敢想
    diagnostics
        110
    diagnostics  
       2024-07-11 09:42:13 +08:00
    @cheng6563 #109 哪里来这些降智言论。

    带解释器的语言,内存占用都不会低,别人说 js 占用低,我反驳他而已。

    你来说 jvm 占用比 js 高,那我问问你

    typeof NaN 等于什么?
    0.1 + 0.2 等于什么?
    9 + "1" 等于什么,91 - "1" 又等于什么?
    xiguadao
        111
    xiguadao  
       2024-07-11 10:05:19 +08:00
    @Vegetable 真实,多年以前在菊厂,一个写 vc++的同事不知道编辑器和编译器的区别,
    cheng6563
        112
    cheng6563  
       2024-07-11 10:26:25 +08:00
    @diagnostics 你在说些什么? js 比起 java 占用还不低吗,你发这些题目又是想表达什么?
    Aresxue
        113
    Aresxue  
       2024-07-11 12:56:51 +08:00
    你这个就适合 go ,确实不适合 java ,但和 java 也确实没啥关系了
    diagnostics
        114
    diagnostics  
       2024-07-11 13:35:28 +08:00   ❤️ 1
    @cheng6563 #112

    不愧我给你的标签,降智,杠精。

    你做任何研究了吗?

    同样一段 while sleep(1000) 代码,js 要 15m ,java 只要 14m

    92597 node 0.0 00:00.11 7 0 30 15M 0B 3504K 92597 91889 sleeping
    94005 java 0.0 00:00.28 22 1 87 14M 0B 0B 94005 93035 sleeping



    ```
    public class Main {

    public static void main(String[] args) {

    while (true) {
    try {
    Thread.sleep(1000);
    } catch (Exception e) {
    System.out.println(e);
    System.exit(1);
    }


    }
    }

    }
    ```

    ```
    function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    }

    async function main() {
    while (true) {
    try {
    await sleep(1000);
    } catch (e) {
    console.log(e);
    process.exit(1);
    }
    }
    }

    main();
    ```
    diagnostics
        115
    diagnostics  
       2024-07-11 13:37:23 +08:00
    @cheng6563 #112 除了嘴炮你还会点啥?拿企业级应用和一个脚本引擎比内存占用?跑单个应用怎么不说话了?我这还是 Java8 ,在 Java21 里,这段代码只需要 12M:

    ```
    95420 java 0.0 00:00.05 20 1 108 12M 0B 0B 95420 93035 sleeping
    ```
    cheng6563
        116
    cheng6563  
       2024-07-11 13:46:46 +08:00
    @diagnostics 讨论技术就讨论技术,没两句话就人生攻击,都开始喷起来了,还发这些东西有啥用。block 了再见。
    bill110100
        117
    bill110100  
       2024-07-11 15:20:01 +08:00
    @cheng6563 hotspot 是 oracle 的,从一开始就准备的面对大企业的应用,连个内存的买不起的小公司,有钱给 oracle 付费吗? java 追求的就是高吞吐,你觉得是没几个功能,程序怎么知道你这几个功能的实际访问量有多大?占内存更不用说,真吞吐暴增的时候,你再和系统申请内存来不及。
    cheng6563
        118
    cheng6563  
       2024-07-12 09:05:57 +08:00
    @bill110100 所以问题不还是占内存吗
    mark2025
        119
    mark2025  
       2024-07-12 12:07:00 +08:00
    @diagnostics 你是觉得 nodejs 很占内存吗?
    mark2025
        120
    mark2025  
       2024-07-12 12:09:34 +08:00
    @YassoWithSpeaker 实际上一个正常的项目多数是用 spring 全家桶开发的,没有 2G 内存很容易 oom ,通常要开 4G 内存。
    diagnostics
        121
    diagnostics  
       2024-07-12 14:57:20 +08:00
    @mark2025 #119 不看应用,只看 node 的话,跑一个 while 比 java 吃内存,你可以按我的代码跑一下试试就知道了。。。。
    vishun
        122
    vishun  
       2024-07-13 11:59:52 +08:00
    @diagnostics #101 chrome 大部分用 c++写的啊。
    bill110100
        123
    bill110100  
       2024-07-13 15:58:20 +08:00
    @cheng6563 占用内存怎么能叫问题?放到单个请求占内存没几个比 java 低的。你觉得 java 占内存,实际用不到,那是你一开始就选错语言了。
    mark2025
        124
    mark2025  
       2024-07-13 20:54:40 +08:00
    @diagnostics 但就语言本身,java, js, C 这些执行器占用内存差不了太多。放到应用框架层面 spring 全家桶吃内存太夸张了,换来的是应用开发各方面都比较友好。
    lingalonely
        125
    lingalonely  
       2024-07-14 13:14:48 +08:00
    直接编译成 native 看会不会下降
    1  2  
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   992 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:44 · PVG 06:44 · LAX 15:44 · JFK 18:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.