Java中创建的OutOfMemoryError对象在哪里 [英] Where is the OutOfMemoryError object created in Java

查看:31
本文介绍了Java中创建的OutOfMemoryError对象在哪里的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

OutOfMemoryError 当堆没有足够的内存来创建新对象时发生.如果堆没有足够的内存,OutOfMemoryError 对象在哪里创建.我正在努力理解这一点,请指教.

An OutOfMemoryError occurs when the heap does not have enough memory to create new objects. If the heap does not have enough memory, where is the OutOfMemoryError object created. I am trying to understand this, please advise.

推荐答案

当然,这是一个依赖于实现的行为.HotSpot 有一些普通分配无法访问的堆内存,JVM 可以用来构造一个 OutOfMemoryError .但是,由于 Java 允许任意数量的线程,任意数量的线程可能同时撞墙时间,因此无法保证内存足以为它们中的每一个构造一个不同的 OutOfMemoryError 实例.

Of course, this is an implementation-dependent behavior. HotSpot has some heap memory inaccessible for ordinary allocations, the JVM can use to construct an OutOfMemoryError in. However, since Java allows an arbitrary number of threads, an arbitrary number of threads may hit the wall at the same time, so there is no guaranty that the memory is enough for constructing a distinct OutOfMemoryError instance for each of them.

因此,在 JVM 启动时会创建一个紧急的 OutOfMemoryError 实例,并在整个会话中持续存在,以确保即使确实没有剩余内存也可以抛出错误.由于该实例将为遇到错误的所有线程共享,而实际上没有剩余内存,因此您将通过该错误将没有堆栈跟踪这一事实来识别这种无关情况.

Therefore, an emergency OutOfMemoryError instance is created at the JVM startup persisting throughout the entire session, to ensure, that the error can be thrown even if there is really no memory left. Since the instance will be shared for all threads encountering the error while there’s really no memory left, you will recognize this extraneous condition by the fact that this error will have no stack trace then.

下面的程序

ConcurrentHashMap<OutOfMemoryError,Integer> instances = new ConcurrentHashMap<>();

ExecutorService executor = Executors.newCachedThreadPool();
executor.invokeAll(Collections.nCopies(1000, () -> {
             ArrayList<Object> list = new ArrayList<>();
             for(;;) try {
                 list.add(new int[10_000_000]);
             } catch(OutOfMemoryError err) {
                 instances.merge(err, 1, Integer::sum);
                 return err;
             }
         }));
executor.shutdown();
System.out.println(instances.size()+" distinct errors created");
instances.forEach((err,count) -> {
    StackTraceElement[] trace = err.getStackTrace();
    System.out.println(err.getClass().getName()+"@"+Integer.toHexString(err.hashCode())
      +(trace!=null&&trace.length!=0? " has": " has no")+" stacktrace, used "+count+'x');
});

-Xmx100Mjdk1.8.0_65下运行,等了半分钟给我

running under jdk1.8.0_65 with -Xmx100M and waiting half a minute gave me

5 distinct errors created
java.lang.OutOfMemoryError@c447d22 has no stacktrace, used 996x
java.lang.OutOfMemoryError@fe0b0b7 has stacktrace, used 1x
java.lang.OutOfMemoryError@1e264651 has stacktrace, used 1x
java.lang.OutOfMemoryError@56eccd20 has stacktrace, used 1x
java.lang.OutOfMemoryError@70ab58d7 has stacktrace, used 1x

表明保留的内存可以服务于四个不同的 OutOfMemoryError 实例的构造(包括记录其堆栈跟踪所需的内存),而所有其他线程必须回退到保留的共享实例.

showing that the reserved memory could serve the construction of four distinct OutOfMemoryError instances (including the memory needed to record their stack traces) while all other threads had to fall back to the reserved shared instance.

当然,不同环境之间的数字可能会有所不同.

Of course, numbers may vary between different environments.

这篇关于Java中创建的OutOfMemoryError对象在哪里的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆