【问题标题】:Where is Thread Object created? Stack or Heap?线程对象在哪里创建?堆栈还是堆?
【发布时间】:2013-10-26 08:16:15
【问题描述】:

当我说这样的话:

Thread t1 = new Thread();

它是在堆还是栈上创建它?

【问题讨论】:

  • “可见”部分在 JVM 堆中。对于正在运行的线程,至少还有一个特定于操作系统的部分被分配到其他地方,但它都是自动处理的。

标签: java multithreading concurrency


【解决方案1】:
Thread t1 = new Thread();

tl;dr 这会在堆中分配对象,即 t1。

随着每个新线程的出现,它都有自己的 pc 寄存器(程序计数器)和 Java 堆栈。如果线程正在执行 Java 方法(不是本地方法),则 pc 寄存器的值指示要执行的下一条指令。线程的 Java 堆栈存储线程的 Java(非本地)方法调用的状态。 Java 方法调用的状态包括its local variables, the parameters with which it was invoked, its return value(如果有)、and intermediate calculations。本地方法调用的状态以与实现相关的方式存储在本地方法堆栈中,也可能存储在寄存器或其他与实现相关的内存区域中。

Java 堆栈由堆栈帧(或帧)组成。堆栈帧包含一个 Java 方法调用的状态。当一个线程调用一个方法时,Java 虚拟机将一个新帧推送到该线程的 Java 堆栈上。当方法完成时,虚拟机弹出并丢弃该方法的帧。

Java 虚拟机没有寄存器来保存中间数据值。指令集使用Java栈来存储中间数据值。

图中显示了正在执行三个线程的虚拟机实例的快照。在快照的瞬间,线程一和二正在执行 Java 方法。线程三正在执行本机方法。它还显示了 Java 虚拟机为每个线程创建的内存区域,这些区域是所属线程的私有区域。没有线程可以访问另一个线程的 pc 寄存器或 Java 堆栈。

【讨论】:

  • 谢谢@Trying!但是可以解释一下什么是线程的本机方法吗?和这个语句 - “本机方法调用的状态以一种依赖于实现的方式存储在本机方法堆栈中,也可能存储在寄存器或其他依赖于实现的内存区域中。”
  • 如果一个线程执行一些本地操作,jni 的东西。对于另一个问题,这意味着 diff os 在线程和空间分配方面有不同的实现。
  • 您好,请说明本机是否包含操作系统级 API 调用?就像在 Java I/O 中调用 read() 、 write() 方法一样。
  • 注意:Java 7/8 确实允许将对象放在堆栈上。
【解决方案2】:

在 Java 8 中,使用 Escape Analysis 可以在堆栈上创建对象。当检测到对象未转义当前方法时会发生这种情况(在执行内联之后)注意:此优化在 Java 7 中可用,但我认为效果不佳。

但是,一旦您调用start(),它就会转义当前方法,因此必须将其放在堆上。

当我说这样的话:

Thread t1 = new Thread();

它是在堆还是栈上创建它?

它可以将它放在堆栈上,前提是您不使用它来创建真正的线程。即如果你是这样

Thread t1 = new Thread(runnable);
t1.start();

它必须把它放在堆上。

【讨论】:

    【解决方案3】:

    在 Java 中没有办法在栈上分配对象。
    堆栈只能保存引用和原语,并且只能保存局部变量。

    请注意,启动一个线程将为该线程创建一个新堆栈。

    【讨论】:

    • +1 更具体地说,Thread 对象及其字段是在堆上分配的。与新线程关联的堆栈内存由 JVM/OS 分配,但它不是在堆上。它被分配在不同的内存部分中。
    • 您不能显式地在堆栈上分配对象,但如果对象足够小并且没有转义当前线程,JVM 可以在堆栈上分配对象作为优化。请参阅“堆栈分配”部分的这篇文章:ibm.com/developerworks/java/library/j-jtp09275/index.html
    • 注意:Java 7/8 确实允许将对象放在堆栈上。
    • @PeterLawrey:不,它没有。
    • @SLaks docs.oracle.com/javase/7/docs/technotes/guides/vm/… 好的,更具体地说,“服务器编译器从生成的代码中消除了标量可替换对象分配和关联锁。”它通过使用堆栈而不是在堆上创建对象来做到这一点.
    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 2016-12-27
    • 2021-05-25
    • 1970-01-01
    • 2016-03-06
    • 2021-02-05
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多