当前位置: 首页 > 知识库问答 >
问题:

OutOfMemoryError对象在哪里创建 Java

云建木
2023-03-14

当堆没有足够的内存来创建新对象时,会发生OutOfMemoryError。如果堆没有足够的内存,则在哪里创建了OutOfMemoryError对象。我正在努力理解这一点,请提出建议。

共有2个答案

郭俊拔
2023-03-14

它由JVM生成,不受-Xmx或其他参数的限制。为您的程序保留的堆被耗尽,而不是JVM可用的内存。

呼延子安
2023-03-14

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

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

以下程序

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下运行,等待了半分钟

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

显示保留的内存可以用于构造四个不同的< code>OutOfMemoryError实例(包括记录其堆栈跟踪所需的内存),而所有其他线程都必须回退到保留的共享实例。

当然,不同环境下的数字可能有所不同。

 类似资料:
  • 问题内容: 我对应该在哪里放置我的虚拟环境感到困惑。 在我的第一个django项目中,我使用以下命令创建了该项目 然后我进入djangoproject目录并运行命令 在与内部目录相同级别上创建了虚拟环境目录。 这是为特定项目创建virtualenv的错误位置吗? 我给人的印象是,大多数人将所有virtualenvs放在一个完全不同的目录中,例如,然后使用virtualenvwrapper在它们之间

  • 问题内容: 我到处都在搜寻,但似乎找不到清晰的答案… 服务器(我的问题是glassfish)注入用@Context注释的实际objets的机制是什么?更具体地说,如果我想编写一个类似以下内容的类: 那我该怎么办呢?实例化MyObject的位置在哪里,由谁执行,如何执行? 编辑:我看过类似以下内容: 在JAX-RS中使用@ Context,@Provider和ContextResolver http

  • JavaScript对每个创建的对象都会设置一个原型,指向它的原型对象。 当我们用obj.xxx访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype对象,最后,如果还没有找到,就只能返回undefined。 例如,创建一个Array对象: var arr = [1, 2, 3]; 其

  • 我需要创建一个对象(银行),其中包含一组客户端和bankID。我的问题是,我不知道如何在主函数中创建银行。 银行类别: 客户端类: 主要类别: 这些是问题所在: 你必须创建一个程序来模拟银行活动。该系统包括以下模块:银行—客户(客户数组)— idBank(字符串)5 BancAccount — accountNumber(字符串)—金额(浮点)客户—姓名(字符串)—地址(字符串)—账户(银行账户数

  • 我在做一个作业,我得到了下面这个问题。 使用方法创建的字符串对象存储在内存中的哪里? 在恒定池中 在堆上(新操作员对象的区域)

  • 问题内容: 我正在通过放入池中进行研究,以便可以重复使用它。 密码工厂 这就是我在 Example 类中实现的方式 打印池 我在正确的道路上吗?是否可以增加泳池大小? 编辑 @http的答案对我来说很好。但是,如果我有另一种方法,应该怎么写? 任何帮助,将不胜感激 ! 问题答案: 您走在正确的轨道上。构造GenericObjectPool时,可以使用接受GenericObjectPoolConfi

  • 主要内容:显式创建对象,隐含创建对象对象是对类的实例化。对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为。 Java 对象的生命周期包括创建、使用和清除,本文详细介绍对象的创建,在 Java 语言中创建对象分显式创建与隐含创建两种情况。 显式创建对象 对象的显式创建方式有 4 种。 1. 使用 new 关键字创建对象 这是常用的创建对象的方法,语法格式如下: 2. 调用 java.lang.Class 或者 ja

  • 我遇到了一些Java代码: 在Java中,我第一次遇到一个构造函数或方法,它的参数是一个接口的“类型”。可以创建接口的对象吗?你能像普通物体一样使用它们吗? 在C语言中,我知道创建抽象类的对象是不可能的。