mmap句柄超过了系统默认最大值。系统默认最大值可使用
cat /proc/sys/vm/max_map_count
查看,进程使用句柄数可使用
cat /proc/$PID/maps | wc -l
查看。每一块申请的ByteBuffer都对应一个mmap句柄,也就是说,如果生成了大量的碎ByteBuffer,那么句柄数也会急剧增长。而这些句柄的回收是伴随着ByteBuffer回收的,堆外内存的GC需要显示调用System.gc来进行。
解决方式:
- 若为32-bit JVM,可升级到64-bit,获得更大的地址空间。
- 若为64-bit JVM,当超出堆外内存不多且使用总内存小于32GB时,使用-XX:useCompressedOops来压缩对象的空间大小。
- 调整-XX:maxDirectMemorySize来获得更多的堆外内存。
- 调整/proc/sys/vm/max_map_count。