之前一直在用 Java 写 企业级代码,并没有很在意 java 的内存问题,比如多个/少个一两百兆就没关心。
平时用 java 写的直接运行就结束的代码,基本都是本地电脑运行,也没有发现内存问题。
直到最近,用 java 写了一个简单的程序,运行在我的 1C1G 的腾讯云机器上,才发现 java 确实内存大户。
程序的功能为:
这就是这个程序的所有功能,由于用到了定时任务和操作 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 了,还是这个内存表现,失望啊。
我用python 写了核心功能,内存占用 20M。
又用quarkus-graalvm 完全1:1重构了一遍,内存占用50M。 详见这个帖子 https://www.v2ex.com/t/1057699
101
diagnostics 120 天前 1
@mark2025 你是觉得 chrome 不占内存吗?
|
102
wuyiccc 120 天前
java 是这样的,垃圾语言,我已经换 go 了
|
103
baoshijiagong 120 天前
小内存机器打开 swap ,程序就不会那么容易 oom 了。写程序的关注点要注意好,java 的关注点本来就不是内存。内存贵还是时间贵。
|
104
likeman 120 天前 via Android
如果功能就是楼主这种简单需求的话,可以试试 nodejs
|
105
Dream95 120 天前
爆点太多,以至于我都不知道该如何吐槽了
|
106
NikoXu 120 天前
shell 就能搞定吧 , 搞什么 java
|
107
YassoWithSpeaker 120 天前
@cheng6563 看了真的很多人都不知道,jvm 启动默认 1/4 内存,这个建议百度下,很多人都说 java 占内存,spring 占内存,那 JavaME 还能跑在诺基亚上,咋不提占内存。
|
108
cheng6563 120 天前
@YassoWithSpeaker 就不是这个问题,假如你 jvm 稳定运行时占 1g 内存,这时你设置 Xmx2g 和 Xmx4g 没有啥区别。
问题是为啥没几个负载没多少功能的 Java 程序为什么要那么多内存,难道每个程序都要进行压测仔细分析负载然后配一个恰到好处的 Xmx 吗。 JavaME 不占内存,ART 不占内存,openj9 也不占内存,为啥就 Hostpot 占内存呢。 |
109
cheng6563 120 天前
@diagnostics 有一说一 Chrome 绝对比 Hostpot 要省内存,要是 Chrome 用 Java 重写,每个标签页都一个进程,那内存占用是不敢想
|
110
diagnostics 119 天前
@cheng6563 #109 哪里来这些降智言论。
带解释器的语言,内存占用都不会低,别人说 js 占用低,我反驳他而已。 你来说 jvm 占用比 js 高,那我问问你 typeof NaN 等于什么? 0.1 + 0.2 等于什么? 9 + "1" 等于什么,91 - "1" 又等于什么? |
112
cheng6563 119 天前
@diagnostics 你在说些什么? js 比起 java 占用还不低吗,你发这些题目又是想表达什么?
|
113
Aresxue 119 天前
你这个就适合 go ,确实不适合 java ,但和 java 也确实没啥关系了
|
114
diagnostics 119 天前 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(); ``` |
115
diagnostics 119 天前
@cheng6563 #112 除了嘴炮你还会点啥?拿企业级应用和一个脚本引擎比内存占用?跑单个应用怎么不说话了?我这还是 Java8 ,在 Java21 里,这段代码只需要 12M:
``` 95420 java 0.0 00:00.05 20 1 108 12M 0B 0B 95420 93035 sleeping ``` |
116
cheng6563 119 天前
@diagnostics 讨论技术就讨论技术,没两句话就人生攻击,都开始喷起来了,还发这些东西有啥用。block 了再见。
|
117
bill110100 119 天前
@cheng6563 hotspot 是 oracle 的,从一开始就准备的面对大企业的应用,连个内存的买不起的小公司,有钱给 oracle 付费吗? java 追求的就是高吞吐,你觉得是没几个功能,程序怎么知道你这几个功能的实际访问量有多大?占内存更不用说,真吞吐暴增的时候,你再和系统申请内存来不及。
|
118
cheng6563 118 天前
@bill110100 所以问题不还是占内存吗
|
119
mark2025 118 天前
@diagnostics 你是觉得 nodejs 很占内存吗?
|
120
mark2025 118 天前
@YassoWithSpeaker 实际上一个正常的项目多数是用 spring 全家桶开发的,没有 2G 内存很容易 oom ,通常要开 4G 内存。
|
121
diagnostics 118 天前
@mark2025 #119 不看应用,只看 node 的话,跑一个 while 比 java 吃内存,你可以按我的代码跑一下试试就知道了。。。。
|
122
vishun 117 天前
@diagnostics #101 chrome 大部分用 c++写的啊。
|
123
bill110100 117 天前
@cheng6563 占用内存怎么能叫问题?放到单个请求占内存没几个比 java 低的。你觉得 java 占内存,实际用不到,那是你一开始就选错语言了。
|
124
mark2025 116 天前
@diagnostics 但就语言本身,java, js, C 这些执行器占用内存差不了太多。放到应用框架层面 spring 全家桶吃内存太夸张了,换来的是应用开发各方面都比较友好。
|
125
lingalonely 116 天前
直接编译成 native 看会不会下降
|