JVM为什么即使内存达到最大堆大小也不会抛出内存不足错误?

huangapple go评论76阅读模式
英文:

Why JVM doesn't throw out of memory error even if the memory reached the maximum heap size?

问题

我正在运行一个Java程序在while循环内部创建了更多的内存对象
我将最大堆大小设置为10MB我在任务管理器中观察JVM甚至在超过10MB后仍在运行
我期望出现内存溢出错误但实际上没有抛出异常而是在while循环中不断打印一条语句

**`java -Xmx10m Main`**

public class Main
{
    public static void main(String[] args) {
        System.out.println("Hello World");
        String s1 = "01011001100100";
        char[] charArray = s1.toCharArray();
        int index = 0;
        StringBuffer result = new StringBuffer();
        StringBuffer temp = new StringBuffer();
        
        while(index < charArray.length){
            System.out.println(index + " : " + charArray[index]);
            if(charArray[index] == '1' && charArray[index--] == '0'){ ***--- 这是有问题的代码***
                result.append(1);
            } else {
                temp.append(charArray[index]);
            }
            index++;
        }
        System.out.println("Result >" + result);
    }
}
英文:

I am running a Java programming which creates more objects in memory inside a while loop.
I set the maximum heap size as 10MB. I am watching task manager, the JVM runs even after 10 MB.
I am expecting out of memory. But it is not throwing , it is keep printing a statement in while loop.

java -Xmx10m Main

public class Main
{
	public static void main(String[] args) {
		System.out.println(&quot;Hello World&quot;);
		String s1 = &quot;01011001100100&quot;;
		char[] charArray = s1.toCharArray();
		int index = 0;
		StringBuffer result = new StringBuffer();
		StringBuffer temp = new StringBuffer();
		
		while(index &lt; charArray.length){
		    System.out.println(index+&quot; : &quot;+charArray[index]);
		    if(charArray[index] == &#39;1&#39; &amp;&amp; charArray[index--] == &#39;0&#39;){ ***--- This is buggy code***
		        result.append(1);
		    } else {
		        temp.append(charArray[index]);
		    }
		    index++;
		}
		System.out.println(&quot;Result &gt;&quot;+result);
	}
}

Thanks

答案1

得分: 1

因为-xmx参数设置的是Java虚拟机的最大堆大小,而不是Java进程的总内存大小。很多JVM内存的使用并不在堆中,包括:

  • 用于保存java可执行文件和共享本地库的代码的内存
  • 用于本地堆的内存,比如本地代码中的malloc调用
  • 用于元空间的内存
  • 用于线程栈的内存
  • 在将文件映射到内存时使用的内存
  • 等等。

上述情况中的一些可能会导致OOME(例如,无法分配新的线程栈),但是使用-xmx设置的堆大小不会以任何方式限制它们。

英文:

> Why JVM doesn't throw out of memory error even if the memory reached the maximum heap size?

Why?

Because the -xmx parameter sets the maximum Java heap size, NOT the total memory size for the Java process. A lot of a JVM's memory utilization is not in the heap. This includes:

  • memory used to hold the code for the java executable and shared native libraries
  • memory used for the native heap; e.g. malloc calls in native code
  • memory used for metaspace
  • memory used for thread stacks
  • memory used when a file is mapped into memory
  • and so on.

Some of the above can lead to an OOME (for example, failure to allocate a new thread stack), but the heap size that you set with -xmx does not limit them in any way.

huangapple
  • 本文由 发表于 2020年9月4日 14:24:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63735895.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定