Java中的OOM
java.lang.StackOverflowError
java.lang.OutMemoryError:Java heap space
java.lang.OutMemoryError:GC overhead limit exceeded:Gc回收时间过长会发生outofmemoryerror,过长的定义是,如果超过98%的时间来做GC,并且回收了不到2%的堆内存,连续多次回收不到2%的情况会跑出,负责形成恶性循环,gc清理的内存再次被填满,迫使gc再次执行。
/*
-Xmx10m -Xms10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
*/
public static void main(String[] args){
int i = 0;
List
try{
while (true){
list.add(String.valueOf(new Random().nextInt(1111111)).intern());
}
}catch (Throwable e){
e.printStackTrace();
}
}
java.lang.OutMemoryError:Direct buffer memory:写NIO程序使用ByteBuffer来读取或者写入数据,这是基于通道(channel)和缓冲区(buffer)的IO方式,可以使用Native函数库直接分配堆内存,然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作,这样在一些场景中能够提高性能,避免了Java堆和native堆中来回复制数据。
ByteBuffer.allocate(capability)第一种方式分配JVM内存,属于GC管辖范围,需要拷贝所以速度相对较慢
ByteBuffer.allocateDirect(capability)第二种方式分配OS本地内存,不属于GC管辖范围,由于不需要内存拷贝,故而速度较快
/*
-Xmx10m -Xms10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
*/
static void directMemory(){
System.out.println("配置的MaxDirectMemory:" + sun.misc.VM.maxDirectMemory()/ (double)1024 / 1024 + "MB");
ByteBuffer.allocateDirect(6 * 1024 * 1024);
}
java.lang.OutMemoryError:unable to create new native thread:在高并发请求服务器的时候,一个应用进程创建太多线程,超过系统的承载能力。你的服务器不允许应用程序创建这么多线程,Linux系统默认一个进程可以创建最多1024个线程(解决办法:减少线程创建或者修改默认服务器配置,扩大默认限制)。
java.lang.OutMemoryError:Metaspace:java8metaspace取代永久代,使用本地内存进行存储。Metaspace是方法与在HotSpot中的实现,即在java8中,classe metadata被存储在Metaspace的native memory(永久代/metaspace:虚拟机加载的类型学,常量池,静态变量,即时编译后的代码)
作者:
shemlo
出处:https://www.cnblogs.com/shemlo
版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。