为什么jvm需要大约10 MB的内存用于简单的hello世界,但clr却没有。这里的权衡是什么,即jvm通过这样做获得了什么?
让我澄清一点,因为我没有传达我脑海中的问题。 jvm和clr运行时之间显然存在架构差异。 jvm具有比clr更高的内存占用。我假设这个开销有一些好处,否则为什么会存在。我在问这两种设计的权衡取舍。 jvm从内存开销中获得了什么好处?
答案 0 :(得分:6)
我猜一个原因是Java必须自己做所有事情(平台独立性的另一个方面)。例如,Swing从头开始绘制它自己的组件,它不依赖于操作系统来绘制它们。这一切都必须在记忆中发生。 Windows可能会做很多东西,但是Linux不能(或做不同的)必须完全包含在Java中,以便它在两者上都能正常工作。
Java也始终坚持认为它的整个库都是“链接”并且可用。由于它不使用DLL(它们不会在每个平台上都可用),所以必须由java加载和跟踪所有内容。
Java甚至做了很多自己的浮点,因为FPU经常会给出不同的结果,这被认为是不可接受的。
因此,如果您考虑C#可以委托给操作系统的所有内容,那么它与Java必须为操作系统补偿其他所有内容相关联,这应该是预期的差异。
我现在在2个嵌入式平台上运行java应用程序。一个是频谱分析仪,它实际上绘制了痕迹,另一个是机顶电缆盒。
在这两种情况下,这个最小内存占用空间都不是问题 - 已经存在Java特定问题,而这些问题并非如此。在这些情况下,实例化的对象数和Swing绘画速度是更大的问题。
答案 1 :(得分: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函数保留或提交虚拟内存。
编辑:
这是我的窗户框中的漂亮照片: alt text http://awise.us/images/mem.png
每个应用程序都是一个简单的printf,然后是getchar。 Java和CLR使用大量虚拟内存。 C版本几乎没有任何东西,所以它的内存使用量相对较小。
我怀疑这两种方式都很重要。只需选择您更熟悉的平台,然后不要编写可怕的,浪费内存的代码。我相信它会有用。
编辑:
来自Microsoft的VMMap tool可能有助于找出内存的来源。
答案 2 :(得分:5)
我不知道初始内存占用或Hello World应用程序的占用空间是否重要。差异可能是由于JVM / CLR加载的库的数量和大小。还可以为垃圾收集池预分配一定量的内存。
我所知道的每个应用程序都使用了很多Hello World功能。这将在整个应用程序执行期间加载和释放内存数千次。如果您对JVM与CLR的内存利用率差异感兴趣,可以使用以下几个带有良好信息的链接
http://benpryor.com/blog/2006/05/04/jvm-vs-clr-memory-allocation/
Memory Management Case study (JVM & CLR)
内存管理案例研究在Power Point中。一个非常有趣的演讲。
答案 3 :(得分:2)
JVM计算其所有共享库是否使用内存。
在报告程序的内存消耗时,任务管理器是不可靠的。你应该把它作为指导。
答案 4 :(得分:2)
JVM在每次运行时都会从rt.jar加载大量不必要的核心类。不幸的是,java包的内部交叉依赖(java.lang< - > java.io)使得部分运行时初始化很困难。更不用说rt.jar本身超过40MB,需要大量的时间进行查找和解压缩。
Post Java 6u10似乎加载了一些更聪明的东西(它有一个jqs.exe = java快速启动服务,可以在内存中保存必要的数据,并且启动速度更快),但Java 7被告知要更好。
Windows中的Process Explorer正确报告专用字节(专用字节是那些不由任何dll共享的内存区域)。
稍微大一点的烦恼是,10年后,JVM仍默认为64MB内存使用量。几乎每次都使用-Xmx真的很烦人,并且只需双击就可以在罐子里运行要求苛刻的程序(除非我改变了文件扩展名赋值的命令)。
答案 5 :(得分:1)
CLR被视为操作系统的一部分,因此任务管理器不报告应用程序进程下的内存消耗。