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

当我说出类似的话:

Thread t1 = new Thread(); 

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

 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调用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堆栈。

在此处输入图像描述

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

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

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

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

当我说出类似的话:

 Thread t1 = new Thread(); 

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

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

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

它必须将它放在堆上。