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

传递给Java线程的对象是否占用堆外空间?,java,multithreading,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 Obje

我有一个物体像:

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对象?换句话说,我是否需要增加堆外内存?我认为Java线程堆栈驻留在那里?如果我的船很大


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

Java通过访问模式来利用堆栈内存,这使得从堆栈中分配和取消分配内存变得非常简单。指针/整数只是简单地递增或递减,而堆在分配或释放内存时涉及更复杂的簿记


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

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

Java是一种通过引用传递的语言,这意味着对象永远不会在方法或线程之间重复。只传递指针,并且 堆栈只保存基本体和指向对象的指针。例如,虽然指向rowsToSubmit对象的指针存储在线程堆栈上,但rowsToSubmit对象内容的内存仍然存储在堆上—内存在线程之间共享

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

进一步阅读:

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

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

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


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

threadObj是一个引用,它存储在堆栈中。它引用的对象在堆中。虽然该语句是正确的,但我对声称Java是按引用传递的语言有点怀疑,因为指针是传递的。Iirc Java本身正式将自己描述为按值传递引用是按值传递的。