我写了一些Java application来记录我的工作活动。因为我每天都打开它,所以最初关心我选择语言的一件事就是它会使用的内存量。
令人高兴的是,在Windows XP下,它通常在最小化时消耗大约5 MB,在最大化时大约消耗大约12 MB,并且愉快地运行-Xmx5M
(根据Windows任务管理器消耗内存)。
当我用更新的硬件升级我的家用电脑,同时升级到Windows 7 64,(虽然我安装并使用32位JVM ),但我立即注意到了JVM根据任务管理器的“工作集”,对于这个应用程序,现在报告68 MB +总是...而且是-Xmx5M -Xss16K
。
旧机器和新机器都有4 GB的RAM,其中512 MB用于视频。两者都在运行Java 6的最新版本 - 关于WinXP的更新15,现在为Win7更新24。磁盘上的应用程序占用量为12 K类70 K.此外,我的工作计算机仍然是Windows XP,运行Java 6_24,并且它显示了大约12 MB这个相同的应用程序 - 并且相同我的意思是字面意思,因为这两个系统是同步的所有我的开发工具。
作为一名开发人员,我需要了解为什么我的应用程序似乎会扼杀这么多内存。
任何人都可以对此有所了解,并建议如何有意义地减少Java 6应用程序的内存占用量?
修改
答案可能是PermGen过大。根据JVisualVM,我有一堆:
大小:5.2 MB,使用:4.3 MB(峰值)和分配6.2 MB。
但对于PermGen
大小:12.5 MB,使用:4.6 MB(峰值)和分配67.1 MB 。
因此,Win 7中的任务管理器中显示的68 MB是否可以被简单地请求但是未分配的虚拟内存?
编辑2
将PermGen降低到12 MB对进程RAM没有影响,但是JVisualVM确实显示它减少了(显然12 MB构成了某种最小值,因为低于此值对JVVM没有影响)。
答案 0 :(得分:1)
64位操作系统使用64位作为指针大小,而32位操作系统使用32位。这可能只是其中一个原因。
答案 1 :(得分:1)
请记住,Java中的所有内容都是指针(大部分都是如此),因此当切换到64位计算机时,使用64位内存地址时,指针的大小会加倍。
JVM(-XX:+UseCompressedOops)中有一个选项可以打开compressed object pointers。这将使您的内存使用率接近您在32位计算机上看到的水平。
答案 2 :(得分:1)
对于64位JVM,您可以指定一个可以减少64位寻址开销的选项。只要堆低于32GB,它基本上可以将指针压缩回32位。在典型的Java应用程序中,这节省了大约40%的内存。有关详细信息,请参阅Compressed oops in the Hotspot JVM。这是它的选择:
-XX:+UseCompressedOops
请注意,如果在64位操作系统上使用32位JVM,则不会支付64位内存地址的开销(尽管在翻译时需要支付不同的开销,但它非常小)
我认为Windows 7不报告内存使用与XP相同(尽管我没有参考)。因此,为了公平地比较32位与64位,您需要在同一版本的Windows上运行。
答案 3 :(得分:0)
这与64位操作系统无关 - Windows XP和Windows 7在very different ways中使用RAM。
正因为如此,Windows 7几乎始终报告所有程序使用的内存比Windows XP更多。不要担心这 - 这只是因为Windows 7使用你的内存应该是这样的:作为缓存。
答案 4 :(得分:0)
虽然不是全部,但64位平台的PermGen尺寸增加了30%:
-XX:MaxPermSize - 永久代的大小。 [5.0及更新版本:64位VM被缩放 大30%; 1.4 amd64:96m; 1.3.1 -client:32m。]