即使没有内存,我会遇到java.lang.OutOfMemoryError吗? [英] Will I encounter java.lang.OutOfMemoryError even with no lack of memory?

查看:123
本文介绍了即使没有内存,我会遇到java.lang.OutOfMemoryError吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读揭开java.lang.Out OfMemoryError ,我想知道是否我理解正确了。是的,如果Java VM抛出一个

I was reading Unveiling the java.lang.Out OfMemoryError and I was wondering if I've understood it correctly. Is it true that if the Java VM throws a


java.lang.OutOfMemoryError :请求的数组大小超过VM限制

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

这意味着VM已拒绝创建阵列,因为它已超出预定义的限制(超过VM类似) ,,因为我的堆空间内存不足?

It means that the VM has rejected the creation of an array because it has exceeded a pre-defined limit (exceeded the likes of the VM), and not because I have run out of memory in the heap space?

我是否正确地说 java .lang.OutOfMemoryError:请求的数组大小超过VM限制并不表示内存不足?

Am I right to say that java.lang.OutOfMemoryError: Requested array size exceeds VM limit does not indicate a lack of memory?

即使我有 unlimited 内存无处不在,Java VM仍然可以抛出 java.lang.OutOfMemoryError:请求的数组大小超过VM限制如果不是比如我创建一个 n 大小数组的请求?

Even if I have unlimited memory everywhere, the Java VM could still throw a java.lang.OutOfMemoryError: Requested array size exceeds VM limit if it doesn't like my request to create an array of n size?

推荐答案

引用带有HotSpot VM的Java SE 6故障排除指南


3.1.3详细消息:请求的数组大小超过VM限制 (内联粗体是我的):

3.1.3 Detail Message: Requested array size exceeds VM limit (inline bold is mine):

详细消息请求的数组大小超过VM限制表示应用程序(或该应用程序使用的API)尝试分配一个大于堆大小的数组。例如,如果应用程序尝试分配512MB的数组但最大堆大小为256MB,则将抛出 OutOfMemoryError ,原因为请求的数组大小超过VM限制。在大多数情况下,问题是配置问题(堆大小太小)或导致应用程序尝试创建大型数组的错误,例如,使用计算不正确大小的算法计算数组中的元素数。

The detail message Requested array size exceeds VM limit indicates that the application (or APIs used by that application) attempted to allocate an array that is larger than the heap size. For example, if an application attempts to allocate an array of 512MB but the maximum heap size is 256MB then OutOfMemoryError will be thrown with the reason Requested array size exceeds VM limit. In most cases the problem is either a configuration issue (heap size too small), or a bug that results in an application attempting to create a huge array, for example, when the number of elements in the array are computed using an algorithm that computes an incorrect size.






更新:受到 @Pacerier 的鼓励我做了一些快速测试。我写了一个示例程序:


UPDATE: encouraged by the @Pacerier I did some quick testing. I wrote a sample program:

public class VmLimitTest {

    public static final int SIZE = 2;

    public static void main(String[] args) throws InterruptedException {
        while(true) {
            byte[] a = new byte[SIZE * 1024 * 1024];
            TimeUnit.MILLISECONDS.sleep(10);
        }
    }
}

并使用以下命令运行JVM选项:

And run it with the following JVM options:

-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails

这就是他们的意思:


  • 整个堆是192 MiB( -Xms192m -Xmx192m

  • 年轻一代(伊甸园+幸存者)空间是64 MiB,老一代是128 MiB( -XX:NewRatio = 2

  • 每个幸存者空间(两个中)是8 MiB,所以48 MiB留给伊甸园(1:6比率, -XX:SurvivorRatio = 6

  • The whole heap is 192 MiB (-Xms192m -Xmx192m)
  • The young generation (eden + survivor) space is 64 MiB, old generation is 128 MiB (-XX:NewRatio=2)
  • Each survivor space (out of two) is 8 MiB, so 48 MiB is left for eden (1:6 ratio, -XX:SurvivorRatio=6)

测试时我发现了以下内容:

While testing I discovered the following:


  • 如果新创建的数组适合eden(小于48 MiB),程序运行良好

  • 令人惊讶的是,当阵列大小超过伊甸园大小时,但可以适应伊甸园和一个幸存者空间(48到56之间) MiB),JVM可以在两个eden上分配单个对象和幸存者(重叠两个区域)。整洁!

  • 一旦数组大小超过eden +单个幸存者(超过56 MiB),新创建的对象将直接放置在旧一代中,绕过伊甸园和幸存者空间。这也意味着突然完全GC一直在执行 - 非常糟糕!

  • 我可以轻松分配127 MiB的数据但是尝试分配129 MiB 会抛出 OutOfMemoryError:Java堆空间

  • If the newly created array can fit into eden (less than 48 MiB), the program runs fine
  • Surprisingly, when the array size exceeds eden size, but can fit into eden and one survivor space (between 48 and 56 MiB), JVM can allocate a single object on both eden and survivor (overlapping two areas). Neat!
  • Once the array size exceeds eden + single survivor (above 56 MiB) the newly created object is placed directly in old generation, bypassing eden and survivor spaces. This also means that suddenly full GC is performed all the time - very bad!
  • I can easily allocate 127 MiB of data but trying to allocate 129 MiB will throw OutOfMemoryError: Java heap space

这是底线 - 你无法创建尺寸大于旧代的物体。尝试这样做会导致 OutOfMemoryError:Java堆空间错误。那么什么时候我们可以预期可怕的请求的数组大小超过VM限制

This is the bottom line - you cannot create an object with size larger than old generation. Trying to do so will result in OutOfMemoryError: Java heap space error. So when can we expect dreadful Requested array size exceeds VM limit?

我尝试运行相同的程序,大得多对象。达到数组长度限制我切换到 long [] 并且可以很容易地达到7 GiB。声明了最大堆128 MiB,JVM仍在抛出 OutOfMemoryError:Java堆空间(!)我设法触发 OutOfMemoryError:请求的数组大小超过VM限制尝试在单个对象中分配8 GiB时出错。我在具有3 GiB物理内存和1 GiB交换的32位Linux计算机上进行了测试。

I tried running the same program with much larger objects. Hitting the array length limit I switched to long[] and could easily go up to 7 GiB. With 128 MiB of max heap declared the JVM was still throwing OutOfMemoryError: Java heap space (!) I managed to trigger OutOfMemoryError: Requested array size exceeds VM limit error trying to allocate 8 GiB in a single object. I tested this on a 32-bit Linux computer with 3 GiB of physical memory and 1 GiB of swap.

据说你可能永远不会遇到这个错误。文档似乎不准确/过时,但在一个结论中确实如此:这可能是一个错误,因为创建如此庞大的数组非常罕见。

That being said you should probably never hit this error. The documentation seems inaccurate/outdated, but it is true in one conclusion: this is probably a bug since creating such huge arrays is very uncommon.

这篇关于即使没有内存,我会遇到java.lang.OutOfMemoryError吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆