当我说出类似的话时:
Thread t1 = new Thread();
它是在堆还是堆栈上创建它?
答案 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堆栈。
答案 2 :(得分:2)
在Java 8中,可以在堆栈上创建使用Escape Analysis对象。当检测到一个对象没有转义当前方法时(在执行内联之后)会发生这种情况。注意:这种优化在Java 7中可用,但我认为它不能正常工作。
但是,只要你调用start()
它就会转义当前方法,因此它必须放在堆上。
当我说出类似的话时:
Thread t1 = new Thread();
它是在堆还是堆栈上创建它?
如果您不使用它来创建真正的线程,它可以将它放在堆栈上。即如果你这样
Thread t1 = new Thread(runnable);
t1.start();
必须将它放在堆上。