关于native memory缺乏引起的OutOfMemory(OOM)问题ITeye - 超凡娱乐

关于native memory缺乏引起的OutOfMemory(OOM)问题ITeye

2019-01-12 09:45:50 | 作者: 碧萱 | 标签: 缺乏,引起,问题 | 浏览: 2305

environment
1.os= win32 2GB RAM
2.jdk=
D:\tools\native_memory java -version
java version "1.6.0_27"
Java(TM) SE Runtime Environment (build 1.6.0_27-b07)
Java HotSpot(TM) Client VM (build 20.2-b06, mixed mode, sharing)

3.demo code
////////begin///////
import java.awt.*;
import java.io.*;

public class ReadLargeFileUnderExhastedNativeMemory {

  public static void main(String[] args) {
try {
 

  String filePath="D:\\work\\vm_files\\NeoShineLinux\\564d4057-070e-3aec-6046-7a461ab5d73e.vmem";//27m
  //D:\\work\\vm_files\\NeoShineLinux\\564d4057-070e-3aec-6046-7a461ab5d73e.vmem;//256m
  //D:\\work\\to_removed\\NC.doc;

  FileInputStream fis = new FileInputStream(filePath); // Any file with size = 501*501*501*2

  int fileSize=fis.available();

  System.out.println("=fileSize is ="+fileSize+"=end=");

  byte buf[] = new byte[fileSize];

  fis.read(buf);

  System.out.println("buf ok");

}
catch (Exception e) {
  e.printStackTrace();
  System.out.println(e);
  System.out.println();
}
  }
/////////end///////
4.读取的文件巨细为256M时,
(1)、由native memory缺乏引起的OOM问题,因为JVM分配了太多的内存(1400M)
D:\tools\native_memory java -Xms1400m -Xmx1400m  ReadLargeFileUnderExhastedNativeMemory
=fileSize is =268435456=end=
Exception in thread "main" java.lang.OutOfMemoryError
  at java.io.FileInputStream.readBytes(Native Method)
  at java.io.FileInputStream.read(FileInputStream.java:198)
  at ReadLargeFileUnderExhastedNativeMemory.main(ReadLargeFileUnderExhastedNativeMemory.java:22)
(2)、正常读取,因为JVM分配较小的内存(512M)
D:\tools\native_memory java -Xms512m -Xmx512m  ReadLargeFileUnderExhastedNativeMemory
=fileSize is =268435456=end=
buf ok
5.【定论】
留意日志,java.lang.OutOfMemoryError,java.io.FileInputStream.readBytes(Native Method),反映的是因为native memory缺乏导致的OOM问题,
而不是由Java heap缺乏引起的。此刻要考虑发作这种问题的原因,是因为native memory内存缺乏,别的需求留意以下现实,
在32-bit的os中,address space最大到4G,而address space又区分为kernel space和user space。windows 32bit下,默许的kernel space和user space分别是2G和2G。
而在user space中,JVM heap +perm 会占用一部分user space,剩余的便是native memory了,当区分了1400M给JVM的heap后,所剩的native memory理论上只要600M了。
并且perm还会占掉一份内存,大约64M,剩余的为600M-64M=546M,并且,理论上要想能读取256M的文件,java heap的最大值应该不小于390M(自己poc过),而os上还运转着
其他的用户进程,也在消耗着user space,最终导致由native memory缺乏引起OOM。

因而,根据OS和hardware(CPU)现已无法改动的条件,需求合理分配JVM的heap最大值,既要统筹application的运用(heap的-Xmx尽可能大),又要统筹native memory不被糟蹋掉(heap的-Xmx尽可能小)。

最终:分给JVM的heap的-Xmx时要合理,不是越大越好,需求针对详细的使用给个合理的值,最好结合GC的战略剖析一段时间heap后,给出合理的heap的-Xmx值。

别的留意以下现实:
I、场景一:
JVM分配1595M,提示初始化jvm失利,阐明不能从native memory区分1595M的memory
D:\tools\native_memory java -Xms1595m -Xmx1595m  ReadLargeFileUnderExhastedNativeMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

可是相同的环境(什么都没有改动,5s钟内)把JVM参数调小1M,能够正常读取27M的文件。
D:\tools\native_memory java -Xms1594m -Xmx1594m  ReadLargeFileUnderExhastedNativeMemory
=fileSize is =27773440=end=
buf ok

可是27M 1M,怎样还能够读取呢?!

II、场景二:
还有:读取256M巨细文件:
D:\tools\native_memory java -Xms1332m -Xmx1332m  ReadLargeFileUnderExhastedNativeMemory
=fileSize is =268435456=end=
buf ok

1338M=1595M-256M 1333M,需求native memory至少大于256M。

D:\tools\native_memory java -Xms1333m -Xmx1333m  ReadLargeFileUnderExhastedNativeMemory
=fileSize is =268435456=end=
Exception in thread "main" java.lang.OutOfMemoryError
  at java.io.FileInputStream.readBytes(Native Method)
  at java.io.FileInputStream.read(FileInputStream.java:198)
  at ReadLargeFileUnderExhastedNativeMemory.main(ReadLargeFileUnderExhastedNativeMemory.java:22)


除了考虑native memory之外,是否要考虑os的page巨细?
********************


VIP:留意:native oom时,除了考虑jvm参数,还需求考虑os的限制参数,

如:

/proc/sys/kernel/pid_max,
/proc/sys/kernel/thread-max,
max_user_process(ulimit -u),
/proc/sys/vm/max_map_count。

可参阅《单个JVM下敞开100w线程数》
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表超凡娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章