Java hello world 确实就要占用 30M

64 天前
 javak

最近看了几个帖子都是说 java 内存的, 自己也写 java , 还从来没关注过一个 hello world, 今天一时兴起测试了下,确实需要占用 30 。

测试方法和代码如下:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("hello memory 02");
        Thread.sleep(60 * 60 * 1000);
    }
}

方式 1: 直接运行 java Main.java 。70M 内存

方式 2: 先编译,再运行: javac Main.java, 然后 java Main. 30M 内存

方式 3 编译成 jar 包在运行,java -jar main.jar 30M 内存。 编译的 maven 配置如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.example</groupId>
    <artifactId>untitled</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <configuration>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>Main</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

以上的 java 运行环境:

openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)

如果觉得上面哪里测试有问题的,欢迎来拍。

一句话总结:Java 内存没救了,在意内存别用 Java 。

11448 次点击
所在节点    Java
113 条回复
CSM
63 天前
@itakeman #96 相比常见的语言有一些新颖的概念,可能会有一些难度;但是工具链很完善,慢慢试错就行了。
zoharSoul
63 天前
@fantastM #70 互联网哪有的销售?
james122333
63 天前
@whyso

java 过度设计 封装太多 坑很多
go runtime 大小相比其它没优势
rust 编译慢占用大 选错方案效能还出不来 撰写也很麻烦
python 效能低硬盘占用又不小的语言 包管理也不好
js 乱七八糟的包一堆 也是封装多 小型解释器还好 含 jit 的都是大容量占用
baoshijiagong
63 天前
测试没问题,结论有问题,“Java 内存没救了”这句有问题。后面那句也改成 “如果特别在意内存,别用 Java”。高级语言面前,几十 M 的内存占用不该是关注的重点。况且里面有一些机制,这些占用并不是线性增长的,不是写一个方法 30M ,两个方法 60M ,如果你再写几个方法,会发现占用内存几乎还是那么多。Java 的最大特点是啥,健壮性。节省人力比内存重要多了。

当然,如果你的项目是部署在几十兆的内存机器上,是要慎重用 Java 。如果是在正常的一般有 16G 以上的服务器,应该无视这个问题。
baoshijiagong
63 天前
打个比方,就像去砍柴,如果你要砍很多柴,需要带一把斧头,可以提高效率,看上去是挺重。如果你只要去捡几根树枝,这个时候,你说带斧头去不如徒手去,就说斧头重量方面没救了。这是不对的。
mark2025
63 天前
@james122333 TypeScript 兼顾了 js 的灵活和静态类型的优点
mark2025
63 天前
@baoshijiagong 语言(执行器)本身内存消耗差距不是大问题。主要是 spring 全家桶框架太重,而说道 java 开发基本就是 spring 全家桶……
jqtmviyu
62 天前
@daysv #94

为啥我试了就这两行, 占用了 30M

console.log('Hello World');
setInterval(() => {}, 1000);
daysv
62 天前
@jqtmviyu 我也这两行。 为啥你要 30m
james122333
62 天前
@mark2025

非内建 微软相关
niubiman
62 天前
都来用 c#吧, 用个锤子的 java
codingmiao
59 天前
实验 1 、直接原生 java -jar 跑
我 win10 占内存 36m ,同事的 mac(arm 架构)只有 19m ,win10 简单加几个参数能压到 20 多 m
java -Xmx5m -Xms1m -XX:MaxMetaspaceSize=1m -XX:+UseSerialGC -XX:CompressedClassSpaceSize=1m -Xss512k -Xint -jar nativedemo-1.0-SNAPSHOT.jar
然后拉一下内存使用情况:
Memory used total max usage GC
heap 22M 252M 3986M 0.57% gc.g1_young_generation.count 2
g1_eden_space 4M 62M -1 6.45% gc.g1_young_generation.time(ms) 14
g1_old_gen 12M 184M 3986M 0.32% gc.g1_concurrent_gc.count 0
g1_survivor_space 6M 6M -1 100.00% gc.g1_concurrent_gc.time(ms) 0
nonheap 28M 31M -1 90.20% gc.g1_old_generation.count 0
codeheap_'non-nmethods' 1M 2M 5M 26.09% gc.g1_old_generation.time(ms) 0
metaspace 19M 20M -1 98.64%
codeheap_'profiled_nmethods' 3M 3M 117M 3.27%
compressed_class_space 2M 2M 1024M 0.22%
codeheap_'non-profiled_nmethods' 838K 2496K 120028K 0.70%
mapped 0K 0K - 0.00%
direct 4M 4M - 100.00%
mapped - 'non-volatile memory' 0K 0K - 0.00%

我拿 arthas 拉的,arthas 注入进来后内存有膨胀了一些,你看占用大头都在 metaspace 、codeheap 以及 old_gen 上,这 hello world 又没 new 啥对象,old_gen 肯定是一些 static 的对象了,这就说明了这些内存是基本消耗,不会随着你的应用增长。

实验 2 、native 打包
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>native-image</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${mainClass}</mainClass>
</configuration>
</plugin>
</plugins>
</build>

这个打完在 x64 的 kali 下运行只占 8m ,在 arm 架构下还会更低。


在复杂场景下,实验 1 以及诸多大厂的生产环境都证明了 java 的稳定可靠,实验 2 则说明如果确实需要在物联网终端等内存极其苛刻的场景下使用,native 也能胜任。所以 Java 内存没救了?你要救什么?
nieyuanhong
21 天前
dO yOu GuYs NoT hAvE mEmOrY?

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

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

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

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

© 2021 V2EX