线程对象在哪里创建?堆栈还是堆?

时间:2013-10-17 17:38:43

标签: java multithreading concurrency

当我说出类似的话时:

Thread t1 = new Thread();

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

3 个答案:

答案 0 :(得分:10)

无法在Java中在堆栈上分配对象 堆栈只能保存引用和基元,并且只能保存局部变量。

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

答案 1 :(得分:9)

Thread t1 = new Thread();

这会分配对象,即堆中的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堆栈存储中间数据值。

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

enter image description here

答案 2 :(得分:2)

在Java 8中,可以在堆栈上创建使用Escape Analysis对象。当检测到一个对象没有转义当前方法时(在执行内联之后)会发生这种情况。注意:这种优化在Java 7中可用,但我认为它不能正常工作。

但是,只要你调用start()它就会转义当前方法,因此它必须放在堆上。

  

当我说出类似的话时:

Thread t1 = new Thread();
     

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

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

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

必须将它放在堆上。