繁体   English   中英

为什么我得到堆outOfMemory异常?

[英]Why do I get heap outOfMemory exception?

我正在尝试分配一个大矩阵(大约10GB)。 我正在使用64位JVM的64位机器。 然后我的进程应该有2^64字节可用,并且我已经将JVM堆大小设置为128G(如果重要的话,我的机器中有16GB的RAM)。 我的理解是我应该从操作系统获取内存,操作系统会将不需要的矩阵单元换出。 但是我得到了上述异常。

编辑:

这就是我定义矩阵的方式:

Jama.Matrix A = new Matrix(num_words, num_documents);

其中num_words约为100k, num_documents约为35k。 另外值得一提的是,这种类型是double

EDIT2:

相关标志:

-Xms40m
-Xmx128g
-d64

在这方面,JVM作为本机进程工作:JVM从OS请求内存,可以在交换机的RAM中分配它。

您可以在java中分配的内存不依赖于您的RAM,而是依赖于您在运行JVM时指定的命令行选项-Xmx 如果RAM内存不足,JVM会从交换中接收它(我相信)甚至不知道这一点。

然而,

  • 在某些操作系统(Windows XP)中,限制为4G。
  • JVM中的堆不是为了从磁盘上运行而设计的。
  • 互换是有限的。

如果您需要处理大数据,则需要使用BigMemory产品(EhCache或Terracotta)。

最后,运行jvisualvm或使用-verbose:gc查看堆分配。

这里有一些描述:

Xms -> the init memory that should be allocated in the start up in MB.
Xmx -> the Max amount of memory that your application can get in MB e.g Xmx2048m.
-XX:MaxNewSize= -> the max S1 and S2 memory size
-XX:NewSize= -> init S1 and S2 size

所以在你的情况下,如果你想尽可能多地分配内存,那么你需要说例如16 * 1024 = 16384 or 16g-XX:MaxNewSize= and -XX:NewSize=将它设置为你的40% XMX

你应该知道一些事情。

  • 托管内存不能很好地交换。 事实上,它通常会导致您的应用程序死亡或您的操作系统锁定(尤其是如果甚至交换10%的堆,您必须重启电源)
  • 堆被分成多个区域,它不会像您期望的那样始终调整大小。 通常它会将这些区域缩放在一起,例如它会使年轻和终身空间1:8,即你不能轻易地同时抓住几乎所有的堆。 我会尝试最大192 GB的堆。
  • 大多数高级进程支持48位地址空间或256 TB虚拟内存,仅支持40位实际内存(每个处理器1 TB)
  • -d64仅适用于Solaris。

简而言之,您需要大约256 GB的主内存和大堆,您真正考虑的是您在做什么。 随机访问内存比访问磁盘空间快一百万倍,这意味着它不仅速度慢一百万倍,而且根本不可能工作。

你可以做的就是使用堆内存,如果你真的知道你在做什么,你可以使它工作,并且可能只比你需要的内存慢100倍。 esp如果你使用快速SSD进行交换,或者你的矩阵是稀疏的,那就是正确的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM