java.lang.StackOverflowError
java.lang.OutOfMemoryError: Java Heap Space
java.lang.OutOfMemoryError: GC overhead limit exceeded
java.lang.OutOfMemoryError: Direct buffer memory
java.lang.OutOfMemoryError: unable to create new native thread
java.lang.OutOfMemoryError: Metaspace
easy:
-
java.lang.StackOverflowError
: 栈递归调用过深 -
java.lang.OutOfMemoryError: Java Heap Space
: heap因为new
对象过多撑爆
GC overhead limit exceeded
GC overhead limit exceeded Demo
VM options
:
-Xmx5m -Xmx5m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
java.lang.OutOfMemoryError: GC overhead limit exceeded
: 多: heap中的对象都不同intern()
并且有引用,CPU >98%全部耗在GC上,但是GC实际上并没有什么卵用。
[Full GC (Ergonomics) [PSYoungGen: 1024K->1024K(1536K)] [ParOldGen: 4030K->4030K(4096K)] 5054K->5054K(5632K), [Metaspace: 3218K->3218K(1056768K)], 0.0186593 secs] [Times: user=0.10 sys=0.00, real=0.02 secs]
.....
[Full GC (Ergonomics) [PSYoungGen: 1024K->0K(1536K)] [ParOldGen: 4041K->474K(4096K)] 5065K->474K(5632K), [Metaspace: 3218K->3218K(1056768K)], 0.0046420 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
************i777
Heap
PSYoungGen total 1536K, used 161K [0x00000007bfe00000, 0x00000007c0000000, 0x00000007c0000000)
eden space 1024K, 15% used [0x00000007bfe00000,0x00000007bfe28a80,0x00000007bff00000)
from space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
to space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
ParOldGen total 4096K, used 474K [0x00000007bfa00000, 0x00000007bfe00000, 0x00000007bfe00000)
object space 4096K, 11% used [0x00000007bfa00000,0x00000007bfa76b38,0x00000007bfe00000)
Metaspace used 3256K, capacity 4500K, committed 4864K, reserved 1056768K
class space used 354K, capacity 388K, committed 512K, reserved 1048576K
java.lang.OutOfMemoryError: GC overhead limit exceeded
...
NIO
: Direct Buffer Memory (直接内存溢出)
写NIO的程序经常用ByteBuffer读取/写入数据,这是一种基于通道(Channel)和缓冲区(buffer)的IO方式;ByteBuffer可以直接分配堆外内存,然后通过JVM堆内DirectByteBuffer对象作为这个对象的引用。因为NIO是要从物理内存出去,直接分配在堆外:避免了Java堆和Native堆中来回分配数据,显著提高性能。
-
ByteBuffer.allocate(capacity)
: 1. 分配JVM堆内存,属于GC,因为需要拷贝所以慢 -
ByteBuffer.allocateDirect(capa)
: 2. 分配OS本地内存,不属于GC,不需要内存拷贝,所以快
但是如果不断分配本地内存,堆内存很少使用,那么JVM就不GC,DirectByteBuffer 对象们就不会被回收;
这个时候堆内存充足,但是本地内存可能用光了,地基不稳,再次尝试分配本地内存就OOM了
DirectBufferMemoryDemo
[GC (Allocation Failure) [PSYoungGen: 1024K->480K(1536K)] 1024K->480K(5632K), 0.0009465 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
配置的maxDirectMemory:5.0MB
[GC (System.gc()) [PSYoungGen: 1315K->496K(1536K)] 1315K->576K(5632K), 0.0008687 secs] [Times: user=0.00 sys=0.01, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 496K->0K(1536K)] [ParOldGen: 80K->457K(4096K)] 576K->457K(5632K), [Metaspace: 3115K->3115K(1056768K)], 0.0046424 secs] [Times: user=0.02 sys=0.00, real=0.00 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:694)
at java.nio.DirectByteBuffer.(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
at com.lei.concurrentandjvm.oom.DirectBufferMemoryDemo.main(DirectBufferMemoryDemo.java:28)
Heap
PSYoungGen total 1536K, used 104K [0x00000007bfe00000, 0x00000007c0000000, 0x00000007c0000000)
eden space 1024K, 10% used [0x00000007bfe00000,0x00000007bfe1a070,0x00000007bff00000)
from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
to space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
ParOldGen total 4096K, used 457K [0x00000007bfa00000, 0x00000007bfe00000, 0x00000007bfe00000)
object space 4096K, 11% used [0x00000007bfa00000,0x00000007bfa727b8,0x00000007bfe00000)
Metaspace used 3163K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 347K, capacity 388K, committed 512K, reserved 1048576K
unable to create new native thread
线程数量过多
UnableCreateNewThreadDemo.java
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
ulimit -u
查看最大一个线程能用线程数
Metaspace
....
省去: cglib代理生产OOM
静态内部类的例子。