关于 Java 笨重一说

2022-05-07 23:31:10 +08:00
 ojh

今天有个帖子是说 Java 笨重、Spring 框架笨重,看完了总结了“笨重”的几点

内存占用多

这个无可厚非,毕竟运行在虚拟机上。但是之前看过一篇博客对比了 Quarkus (印象中) JIT 和 AOT 两种模式下运行内存的占用,启动初期 AOT 完胜 JIT ,但是高负载情况下两者差不多,所以我想了解下是如果同等高负载的情况下,C++/Go 这类的服务端程序的内存占用跟 Java (最新) 比差距大不大呢。

JRE 很大

这个如果在最新 Java 下面用 jlink 并且压缩一下应该 50MB (包含 JavaFX 了,不包含的没试过) 左右,一个带 JRE 的 Java 应用 50MB 应该还可以接受吧。其实我疑惑的是很多人吐槽 JRE 大,没人吐槽 NodeJS 或者 Python 大么

配置很复杂

估计指的是 Servlet 那套 web.xml 配置以及远古时代 Spring 的 context.xml ,这个我也想吐槽,不过 SpringBoot 应该缓解了这个问题

打出来的包很大

Srping/SpringBoot 为了方便开发提供了很多大而全的东西所以很大,如果你的程序就简单的接口,业务代码也很简单,什么依赖注入、切面、请求体转换、参数校验等等功能都用不到,那也没必要用 Spring 框架。顺便问一句有什么好 Java Web 框架脱离 Servlet 体系又很瘦小的

其实对于我这个 Java 菜鸡来说上面问题都不是让我郁闷的,真正让我郁闷的是 Java 为什么这么多规范!这么多规范真的好吗?

8513 次点击
所在节点    程序员
89 条回复
seakingii
2022-05-08 12:10:57 +08:00
另外 Java 的"笨重"还体现在这门语言的语法上,有时为了实现一个功能要写好多的代码.当然现在 Java 本身也在进化,也越来越简洁化.
az467
2022-05-08 12:17:20 +08:00
原因在于 java 流行太早而发展太慢,主流版本(8/11)就是这么烂。

- 内存占用多
主要两点原因,一是 java 大量使用堆内存和引用对象,而且没有值类型或者结构体,就算 jit 能优化成栈上分配,最少也多一个对象头,性能和内存占用天生就弱,调 c/c++ 库也很麻烦。
另一个就是 vm 必须要占用的那一部分,实际上使用到的内存没那么多,但是内存就是被占用掉了,这在云时代更是问题,那都是真金白银呐。
当然啦,相信这些问题将来会被那一大堆 project XXX/GraalVM/aot 优化甚至解决,但是我用 Java8 。
- JRE 很大
这个其实还好,真没啥感觉,云环境也有轻量 base image 可以直接用。
- 打出来的包很大
在 springboot 一统天下的如今,框架不是你想换就换的。
上云的可以试一下 Layered Jar ,多少能缓解一点。
- Servlet 规范
纯历史遗留问题。
- Getter 、Setter
没早点把 Property 抄过来,你看 Kotlin 就很好。
- xxxService/xxxServiceImpl
对业务代码来说,99%的情况下没用,知道是怎么回事然后照本宣科就完事了。

综上,骂了这么多年了,能改的 java 多少快慢都在改进,但是这都跟 java8 用户没有关系。
xiaofan305
2022-05-08 12:22:34 +08:00
以牺牲硬件资源来换取某新便利或稳定,在计算机领域太常见了 。加一层,再加一层,再加一层…
ecloud
2022-05-08 12:37:45 +08:00
node.js 以及依附于之上的什么 angular, vue 那才是又臭又大,但是没办法,纯纯解释性语言,JS 天生有弱鸡,结果诞生出这么一群怪胎
PS:其实早年 Java 想做的其实就是现在 node.js 干得这些事( Applet )
ecloud
2022-05-08 12:43:28 +08:00
@billlee 天下没有免费的午餐,任何抽象都不是零开销的,C++不是,其他任何编译型的 OO 语言也不是。冯诺伊曼体系本质上就是内存跟 CPU 跳二人转,一个人想清闲那就必须把任务加到另一个人身上,没有白捡的。Java 天生缺陷不是 OO 问题,而是他的虚拟机体系。人家本来天生就不是想用来做大型程序的,OO 特性只是附加的东西。Java 原始设计目的真正的精神续作其实是安卓
ojh
2022-05-08 12:44:06 +08:00
@statumer Spring Webflux + Spring Data R2DBC 又会如何呢,本人没用过 Spring Data R2DBC ,Java 的响应式编程要写异步代码这块真的不容易 。不过 Java19 已经 preview loom (希望 Value Object 也可以)了,但是这个让主流框架适配不知道猴年马月
yedra
2022-05-08 12:54:23 +08:00
@geekvcn 别人好歹是在求教,你在干什么
chocotan
2022-05-08 13:55:57 +08:00
我本来也打了一堆,最后还是删掉了,感觉国内很多人的认知还是停留在好多年前
------
说说我自己的使用情况吧,我最近在自己搭建一些工具,用了不少其他语言的应用,它们的大小也不小,某些极品应用能直接把服务器内存给干爆( oom killer ),最后我不得不用 java 自己写了个
Lancer777
2022-05-08 14:14:13 +08:00
其实说难听点就是大部分程序员还是脚本小子,有没有规范,有没有团队协作都是不重要的,自己开心就好。还有吹 Go 生态的,Go 社区现在做的事情不就是把 Java 做的事情重新做一遍吗?有啥区别?如果多看点架构设计、软件工程的书,就能明白 Java 这叫高度工程化,绝对算不上笨重和臃肿,难道建摩天大楼的地基和楼体支撑也叫笨重和臃肿吗?
chihiro2014
2022-05-08 14:16:50 +08:00
模块化可以省掉很多没必要的东西
fengjianxinghun
2022-05-08 14:20:25 +08:00
反正一个应用要是 java 写的,我直觉上就会找个其他 c/c++/rust/go 的替代品,除非别无选择
nl101531
2022-05-08 14:23:14 +08:00
这种算是遗留下来的习惯式规范,不过有了 lombok 也还好了。 自己的项目可以使用充血模型体验不一样的开发乐趣,公司的项目还是按照大家都习惯的方式来,沟通成本小了很多,其实规范多不一定是坏事。
ojh
2022-05-08 14:29:14 +08:00
@Lancer777 你说的规范、团队协作、工程化有道理,虽然 Java 搞这么多的规范分这么多层看上去很啰嗦,但是可以让能力经验参差不齐的人写的代码都保持一定的统一,利于团队合作和代码维护
iseki
2022-05-08 14:35:57 +08:00
setter & getter 是 Java 没有 property 导致的,<del>就像 Go 一样,写编译器的省事了,程序员就费事了</del>,直接暴露 field 是不合适的。
zhouzm
2022-05-08 16:39:28 +08:00
唉,现在很多人已经丧失了,认真阅读理解别人的文字,以及好好说话这两种能力。
msg7086
2022-05-08 17:00:55 +08:00
关于 Java 笨重,过度设计,Getter/Setter 这些,我简单说一些。

Getter/Setter ,有一个原因是向前兼容性。
没有逻辑在里面,不代表永远没有逻辑在里面。
如果你暴露一个 public 的字段,那么你暴露的就是一个数据,而操作这个数据的代码,在第三方。换句话说,你的类对你的数据将失去控制能力,任由第三方来读写。数据和操作数据的代码就割裂开来了。
而 Getter/Setter 则是方法,或者说代码,你对内部的数据有最终操作权,而别人只能调用你提供的方法。如果有朝一日这个数据被改变了,被废弃了,或者业务逻辑被加强了,那么你不需要跑到几十个办公室找几十个团队的人抓着他们跟着你改代码。

过度设计也是基于这个准则。假设地球上有一万个中型或者大型项目,并且每个项目都有几十个工程师在工作,每个项目都需要不同的组件来互相搭配,如果不做成接口,不解耦组件,那得浪费多少工程师的时间?

当你用 Java 的时候,你就要把自己摆正到正确的位置上。这是一个更适合大型企业的语言和框架环境,方便几百几千个工程师在一起协作开发,方便让各种能力水平的人都聚到一起工作。有多少语言和框架能做到这样的?不多吧。

我给公司做团队项目,那肯定是用 Java 的。但是我要是自己写项目,或者和志同道合的人一起写,我肯定选择写 Ruby 。三个人的团队写 Java 会很不舒服,三十人的团队写 Ruby 也会很不舒服。不同的语言有不同的特长。
lanlanye
2022-05-08 17:36:00 +08:00
在我这个没写过 Java 项目的外行看来,面向接口编程应该是没什么问题的,准确来说是面向抽象编程,但并不是所有东西都需要抽象,以“考虑未来 /拓展”为理由产生的过度抽象是应该避免的。

关于 Getter/Setter:同 56 楼,是面向对象保持封装性的一部分,但是我个人认为如果你开发的是一个类似 Spring 这样需要一步步发展完善的大型工程项目,那封装是很重要的,反之如果只是写简单的业务逻辑,以后很可能整个 Model 都推翻重来,也不会有人在你这个项目之上再去拓展(感觉一般的 Web 项目模型都不会再作为其他项目的基础了),那么对于不需要限制修改的属性,完全可以写成 public 的。

其他内存问题我不了解,不过直觉多一个 JVM ,不管怎么都不可能和直接在对应平台上编译效果一样吧。
codingadog
2022-05-08 18:02:28 +08:00
世界上只有两种语言:没人用的语言,和被人喷的语言(手动 doge
DOLLOR
2022-05-08 18:19:57 +08:00
我想起之前接手的一个小程序项目,一看就是 java 背景的人写的。因为代码里面出现了大量为了 OO 而强行 OO 的风格。
比如一个 request 请求,传统的 JS 、TS 开发者会把 wx.request 再套一层 async 函数封装就完事了。而他非要用几个 class 套个里三次外三层,结果是每个页面还要把这几个 class Req 再实例化一遍😂。
dcsuibian
2022-05-08 18:33:36 +08:00
本命 Java 。
要是写脚本,Java 那肯定是比不上 Nodejs 、Python 这种动态语言的,写起来真的轻松很多。但要是写服务器上正经的应用,那 Java 属实是强的一批。
1 、就资源占用问题来说,带了 vm 肯定比不上 C 和 C++这种,不适合低性能、低功耗的设备。但 vm 的好处也很大,平台无关性、自动内存管理等等,最主要是省了程序员开发的时间(很值钱的)。(我写过 C 和 C++,内存管理确实不是一件很省心的事)
以前 Java 的 web 程序是打成 war 包放在 Tomcat 里,现在则是直接和 Tomcat 融合成一个 jar 。近年来还出现了各种容器化、虚拟化技术。大厂在资源占用和开发效率中的选择已经很明显了。同时 jvm 极其优秀,虽然资源占用大了点,但性能也不算差,支持多线程,在带 vm 的语言里就是 top class 。

我认为 Java 作为一种偏高级的语言其实在资源、性能、开发效率上做到了一种相当好的平衡。

2 、JRE 很大这个我也觉得很迷惑。搞得好像 js 和 python 不用运行时一样的。.net 倒是好搞,操作系统带了,但非 windows 就比较尴尬。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/851477

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX