16

为什么 jvm 需要大约 10 MB 的内存来实现一个简单的 hello world 而 clr 不需要。这里的权衡是什么,即 jvm 通过这样做可以获得什么?

让我澄清一下,因为我没有传达我脑海中的问题。jvm 和 clr 运行时之间显然存在架构差异。jvm 的内存占用明显高于 clr。我假设这种开销有一些好处,否则为什么会存在。我在问这两种设计的权衡是什么。jvm 从它的内存开销中获得了什么好处?

4

6 回答 6

6

我想一个原因是Java必须自己做所有事情(平台独立性的另一个方面)。例如,Swing 从头开始​​绘制它自己的组件,它不依赖操作系统来绘制它们。这一切都必须发生在记忆中。windows 可以做的很多事情,但 linux 没有(或做不同的事情)必须完全包含在 Java 中,以便它在两者上的工作方式相同。

Java 还始终坚持认为它的整个库都是“链接的”并且可用。因为它不使用 DLL(它们不会在每个平台上都可用),所以一切都必须由 java 加载和跟踪。

Java 甚至做了很多它自己的浮点,因为 FPU 经常给出不同的结果,这被认为是不可接受的。

因此,如果您考虑 C# 可以委托给它所关联的操作系统的所有东西与 Java 必须为操作系统做的所有东西以补偿其他东西,那么应该可以预料到差异。

我现在已经在 2 个嵌入式平台上运行 java 应用程序。一个是实际绘制轨迹的频谱分析仪,另一个是机顶盒。

在这两种情况下,最小的内存占用都不是问题——存在 Java 特定的问题,只是没有。在这些情况下,实例化对象的数量和 Swing 绘制速度是更大的问题。

于 2009-05-16T04:52:32.330 回答
5

似乎java只是使用更多的虚拟内存。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
amwise   20598  0.0  0.5  22052  5624 pts/3    Sl+  14:59   0:00 mono Test.exe
amwise   20601  0.0  0.7 214312  7284 pts/2    Sl+  15:00   0:00 java Program

我用 C# 和 Java 编写了一个测试程序,打印字符串“test”并等待输入。我相信驻留集大小 (RSS) 值更准确地显示了内存使用情况。虚拟内存使用 (VSZ) 意义不大。

据我了解,应用程序可以保留大量虚拟内存,而无需实际使用任何真实内存。例如,您可以要求 Windows 上的VirtualAlloc函数保留或提交虚拟内存。

编辑:

这是我的 Windows 框中的一张漂亮图片: alt text http://awise.us/images/mem.png

每个应用程序都是一个简单的 printf,后跟一个 getchar。Java 和 CLR 使用大量虚拟内存。C 版本几乎不依赖任何东西,因此它的内存使用量相对较小。

我怀疑这是否真的很重要。只需选择您更熟悉的平台,然后不要编写糟糕的、浪费内存的代码。我相信它会成功的。

编辑:

这个来自 Microsoft 的VMMap 工具可能有助于确定内存的去向。

于 2009-05-12T22:13:19.200 回答
5

我不知道初始内存占用或 Hello World 应用程序的占用是否重要。差异可能是由于 JVM / CLR 加载的库的数量和大小。还可以有为垃圾收集池预先分配的内存量。

我知道的每个应用程序都使用了比 Hello World 更多的功能。这将在整个应用程序的执行过程中加载和释放内存数千次。如果您对 JVM 与 CLR 的内存利用率差异感兴趣,这里有几个链接很好的信息

http://benpryor.com/blog/2006/05/04/jvm-vs-clr-memory-allocation/

内存管理案例研究(JVM 和 CLR)

内存管理案例研究在 Power Point 中。一个非常有趣的演示。

于 2009-05-15T03:43:42.973 回答
2

JVM 计算其所有共享库,无论它们是否使用内存。

在报告程序的内存消耗时,任务管理器相当不可靠。你应该把它当作指南。

于 2009-02-05T22:54:02.160 回答
2

JVM 在每次运行时从 rt.jar 加载大量不必要的核心类。不幸的是,java 包的内部交叉依赖(java.lang <-> java.io)使得部分运行时初始化变得困难。更何况 rt.jar 本身超过 40MB,查找和解压缩需要大量时间。

Post Java 6u10 似乎加载的东西更智能了(它有一个 jqs.exe = java 快速启动服务来将必要的数据保存在内存中并进行更快的启动),但 Java 7 仍然被告知要更好。

Windows 中的进程资源管理器正确报告私有字节(私有字节是那些不被任何 dll 共享的内存区域)。

稍大一点的烦恼是,10 年后,JVM 仍然默认使用 64MB 内存。几乎每次都使用 -Xmx 真的很烦人,并且无法通过简单的双击在 jar 中运行要求苛刻的程序(除非我更改文件扩展名分配的命令)。

于 2009-05-18T08:04:48.863 回答
1

CLR 被视为操作系统的一部分,因此任务管理器不会在应用程序进程下报告它的内存消耗。

于 2009-02-05T19:51:22.387 回答