DirectMemory 容量可通过 -XX:MaxDirectMemorySize
指定,如果不指定,则默认与 Java 堆最大值( -Xmx
指定)一样,下面程序利用 DirectByteBuffe 模拟直接内存溢出的情况
Java 堆用于存储对象实例,只要不断地创建对象,并且保证 GC Roots 到对象之间有可达路径来避免垃圾回收机制清除这些对象,则在对象数量到达最大堆的容量限制后就会产生内存溢出异常。因此我们用编写如下代码来模拟内存溢出
Java 永久代是非堆内存的组成部分,用来存放类名、访问修饰符、常量池、字段描述、方法描述等,因运行时常量池是方法区的一部分,所以这里也包含运行时常量池。我们可以通过 jvm 参数 -XX:PermSize=10M -XX:MaxPermSize=10M
来指定该区域的内存大小,-XX:PermSize
默认为物理内存的 1/64 ,-XX:MaxPermSize
默认为物理内存的 1/4 。String.intern()
方法是一个 Native 方法,它的作用是:如果字符串常量池中已经包含一个等于此 String 对象的字符串,则返回代表池中这个字符串的 String 对象;否则,将此 String 对象包含的字符串添加到常量池中,并且返回此 String 对象的引用。在 JDK 1.6 及之前的版本中,由于常量池分配在永久代内,我们可以通过 -XX:PermSize
和 -XX:MaxPermSize
限制方法区大小,从而间接限制其中常量池的容
Java 程序中堆栈( Stack Space )用来做方法的递归调用时压入栈帧( Stack Frame ),每个线程都有自己的堆栈,这个堆栈不是来自 Heap 的分配。所以堆栈的大小不会受到 -Xmx
和 -Xms
的影响,这2个 JVM 参数仅仅是影响 Heap 的大小。虚拟机参数 -Xss
用来指定每个线程的堆栈大小,设定该值后,当递归调用太深的时候,就有可能耗尽堆栈空间,爆出 StackOverflow 的错误,我们使用如下代码做实验: