在过去,我使用C ++或C#创建了大部分内存和性能关键应用程序,但是随着Java语言的最新改进,我想我可能会尝试一下。但是我已经很早就陷入了Java中的内存管理问题。更具体地说,以下两点让我感到惊讶:
我上面提到的例子:
所以我的问题是:为什么Java会这样表现?更重要的是,我能告诉JVM多一点......理智吗? C#也是一种托管语言,但它可以正确地释放未使用的内存。
答案 0 :(得分:4)
为什么我必须告诉JVM它可以使用多少内存?
你没有。它的合理默认最大值为主存储器的1/4,最大为32 GB。
难道不能只使用它想要的东西吗?
可以,您可以将最大值设置为所有可用内存。
我的意思是......拿你需要的东西?
它可以做到这一点,但是你设置的最大值不会影响其他应用程序。
为什么内存如此贪婪?
这取决于你如何使用它。
在向操作系统回放内存方面有多慷慨吗?
这取决于您使用的GC。
开始使用2048mb的堆空间
我认为你的意思是2 GB或2048 MB(mb是一个毫位,而且我很讨厌我的抱怨)
现在这是一个非常少量的内存,我想这只是一个例子。 C.F.我9岁的孩子有一个旧的桌面,有24 GB的内存。
我打开并完全读取一个400mb文件的字节数组 - > 700mb的RAM
我会记忆地映射文件。这几乎不使用堆。顺便说一句你也可以用C和C#来记忆地图,这不是特定于Java的技巧。
我将该数组包装成ByteBuffer - > 700mb的RAM
内存映射文件已经是ByteBuffer。在这一点上你的堆不大。
我将其解密为第二个数组(无法就地完成) - > 1100mb的RAM
我会这样做到另一个“直接”缓冲区。再一次没有使用堆。
我解析解密的数组(产生的数据少一点) - > 1350mb的RAM
所以这使用额外的250 MB。
我将解密数组设置为null - > 1350mb的RAM
这会将引用更改为null
,但不会更改。在任何情况下,这只是你上面的一个缓冲区。
我等了一会儿 - > 1350mb的RAM
如果你什么都不做,你就不会发生任何事情。
如果我用1028mb的堆空间重复上述内容 - > OutOfMemoryException异常
这是因为你保留了记忆,第二次你的记忆力减少了。
简而言之,我会
更重要的是,我能告诉JVM多一点......理智吗?
我怀疑“理智”是旁观者的眼睛。