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线程数》
【温馨提示】
如果您觉得满意,可以选择支持下,您的支持是我最大的动力:
分享到:
相关推荐
Java中的“内存不足OOM (Out Of Memory):java.lang.OutOfMemoryError”是一个常见的运行时错误,它表示Java虚拟机(JVM)在尝试分配新的对象或数据结构时,发现系统内存不足以完成此操作。这个问题通常发生在程序...
7. Out of Space in JVM HEAP 错误 * 原因分析:JVM 的堆内存空间不足 * 解决方案:增加 JVM 的堆内存空间、检查大对象的合理性、添加机器资源、做限流降级 8. Java.lang.OutOfMemoryError: Direct Buffer 错误 *...
在 SpringBoot 中使用 @Async 注解来实现异步操作是一种非常常见的做法,但是如果不小心,可能会导致 OOM(Out of Memory)问题。本文将详细介绍 SpringBoot 中 @Async 默认线程池导致 OOM 问题的原因、解决方法以及...
本教程将涵盖Java的基础知识,特别是关于内存管理的重要概念——Java内存区域、Out of Memory (OOM)错误以及垃圾回收器和垃圾回收策略。 1. **Java入门**: Java的学习始于基础语法,包括变量、数据类型、运算符、...
Android内存优化是提升应用性能和用户体验的关键因素,尤其是在防止Out Of Memory (OOM)错误方面。本文将深入探讨Android内存管理的基础、内存优化策略、Bitmap的使用及管理、内存泄漏的原因和解决方案,以及如何...
在Android开发中,加载本地图片是一项常见的任务,但如果不妥善处理,可能会导致内存溢出(Out Of Memory,简称OOM)问题。本压缩包文件“Android应用源码之加载本地图片,绝对不会出现OOM.zip”提供了避免Android...
在安卓开发中,加载本地图片是一项常见的任务,但如果不妥善处理,可能会引发内存溢出(Out Of Memory,简称OOM)问题。"安卓Android源码——加载本地图片,绝对不会出现OOM.zip"这个压缩包文件显然是针对如何避免在...
`OOM (Out of Memory)`错误是开发者经常遇到的问题,它表明程序在运行时耗尽了可用内存。为了理解和预防这类问题,我们需要深入理解JVM(Java虚拟机)的工作原理,特别是其内存模型、垃圾收集机制以及调优策略。...
#### 八、OutOfMemory错误实例 在实践中,可能会遇到多种类型的`OutOfMemoryError`。例如: - `Java heap space`: 表示堆内存不足。 - `PermGen space`: 在Java 8之前,表示永久代空间不足。 - `Metaspace`: Java ...
文档中提到了京东项目中的实际案例,通过对项目的监控发现存在OOM(Out Of Memory)的问题。通过使用JVM参数进行调整,比如: - 将-Xmx和-Xms设置为相同的值4096M,避免每次垃圾回收后重新分配内存; - 设置年轻代...
接下来,文档提供了一个流程图,概述了Java 5和Java 6的OutOfMemory问题处理流程。如果遇到OOM错误,首先需要收集必须的信息(MustGather)。这是一个合成词,指的是收集对IBM来说用来调试问题有帮助的文件集合。...
在Android开发中,内存管理是至关重要的,尤其是处理大图片时,可能会引发内存溢出(Out Of Memory,简称OOM)问题。这是因为Android设备为每个应用分配的内存是有限的,而大图片会占用大量内存,当应用试图加载过多...
Java内存溢出(Out Of Memory, OOM)是开发者在编程过程中经常遇到的问题,尤其是在处理大量数据或长时间运行的应用程序时。本篇文章将详细解析三种常见的Java内存溢出类型:JVM PermGen space溢出、JVM heap space...
在实际应用中,常见的内存问题包括内存溢出(Out Of Memory, OOM)和内存泄漏。内存溢出通常是因为堆内存不足,可以通过调整JVM参数如 `-Xms` 和 `-Xmx` 来增大堆大小。内存泄漏则指对象无法正常释放,导致可用内存...
Java性能调优主要聚焦在JVM的优化,其中包括内存模型的理解、垃圾收集(GC)机制以及如何处理常见的Out of Memory (OOM)异常。首先,我们要理解JVM的内存模型,这是进行性能调优的基础。 JVM内存模型由堆、栈、方法...
图片加载是内存消耗的大户,合理使用`BitmapFactory.Options`设置解码参数,避免加载过大图片导致OOM(Out Of Memory)错误。 9. **内存快照和比较**: 通过对比不同时间点的内存快照,可以找出内存占用增加的...