传递给Java线程的对象是否会占用堆外空间?

时间:2017-08-08 01:12:43

标签: java multithreading

我有一个像这样的对象:

final List<Rows> rowsToSubmit = new ArrayList<>(rows);

我实例化线程,如:

// submit to a thread
executorService.submit(new Callable<Boolean>() {
  @Override
  public Boolean call() throws Exception {
    Object threadObj = new Object();
    return bq.doHttpPost(rowsToSubmit); // takes about 3 seconds for IO
  }
});

Java是否也利用rowsToSubmit对象的线程堆栈内存?换句话说,如果我的rowsToSubmit很大,我是否需要增加我的堆外内存(我认为Java线程堆栈存在于那里?)?

此外,threadObj是否也在堆外空间初始化了?

3 个答案:

答案 0 :(得分:0)

所有java对象都存储在堆上,因此您不需要配置堆外内存。

Java是一种传递引用语言,这意味着对象永远不会在方法或线程之间重复。只传递指针,和 堆栈只包含对象的基元和指针。例如,当指向rowsToSubmit对象的指针存储在线程堆栈中时,rowsToSubmit对象内容的内存仍然存储在堆上 - 内存在线程之间共享。 / p>

同样,我不会说在堆外空间初始化threadObj因为所有java对象都在堆上。对threadObj的引用存储在堆外空间中。

进一步阅读:http://www.journaldev.com/4098/java-heap-space-vs-stack-memory

答案 1 :(得分:0)

Java Spec

每个Java虚拟机线程都有一个私有Java虚拟机堆栈,与线程同时创建。 Java虚拟机堆栈存储帧(第2.6节)。 Java虚拟机堆栈类似于传统语言的堆栈,例如C:它保存局部变量和部分结果,并在方法调用和返回中起作用。由于除了推送和弹出帧之外,永远不会直接操作Java虚拟机堆栈,因此可以对堆进行堆分配。 Java虚拟机堆栈的内存不需要是连续的。

在Java虚拟机规范第一版中,Java虚拟机堆栈称为Java堆栈。

此规范允许Java虚拟机堆栈具有固定大小或根据计算的需要动态扩展和收缩。如果Java虚拟机堆栈具有固定大小,则可以在创建堆栈时单独选择每个Java虚拟机堆栈的大小。

第二,当你通过参数传递一个对象,因为它总是按值传递。所以如果它不会在堆中创建任何对象,只复制对局部变量的引用,并且两者都将指向同一个对象。

答案 2 :(得分:-1)

Java通过访问模式来利用堆栈内存,这使得从中分配和释放内存变得微不足道(指针/整数简单地递增或递减),而堆在分配或免费中涉及更复杂的簿记。

Java中的每个线程都有自己的堆栈,可以使用 -Xss JVM参数指定,类似地,您也可以使用JVM选项指定Java程序的堆大小 -Xms -Xmx 其中-Xms是堆的起始大小,-Xmx是java堆的最大大小。