pet*_*ter 3 java multithreading memory-management
我想知道如果在方法中声明一个本地线程会发生什么?通常,函数返回后,所有局部变量都将消失,因为它们都在Stack上分配.然而,似乎本地线程将是一个不同的故事.是对的吗?
public int A() {
Thread t = new Thread() {
doSomething();
}
t.start();
return -1;
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*int 14
线程是它自己的GC根.因此,无论何时创建线程,无论其创建上下文如何,在其运行方法完成之前,它都不会准备好GC.即使本地方法完成且线程仍处于活动状态,也是如此.
例:
public void doSomeAsync(){
Thread th = new Thread(new Runnable(){
public void run(){
Thread.sleep(500);
}
});
th.start();
//do something else quickly
}
Run Code Online (Sandbox Code Playgroud)
在//do somethign else quickly没有转义的任何定义之后,该方法被标记为GC.线程th将不会被标记为GC并且正确地放置在具有自己的线程堆栈的堆上.
约翰的答案很好,但我想我会补充一些细节.这是一个代码示例,我将用它来显示特定的变量用法.
public void startThread() {
long var1 = 10;
byte[] var2 = new byte[1024];
final byte[] var3 = new byte[1024];
final byte[] var4 = new byte[1024];
Thread thread = new Thread(new Runnable() {
private long var5 = 10;
private byte[] var6 = new byte[1024];
public void run() {
int var7 = 100;
byte[] var8 = new byte[1024];
System.out.println("Size of var4 is " + var4.length);
baz();
...
}
private void baz() {
long var9 = 2;
byte[] var10 = new byte[1024];
...
}
});
thread.start();
}
Run Code Online (Sandbox Code Playgroud)
所以我们在线程周围分配了许多变量.我们还有Thread对象本身以及Runnable线程正在运行的目标.
startThread(),但是关联Thread也是由JVM管理的.run()方法完成后只有GC'd,Thread并由JVM 收集.在ThreadGC'd之后,所有使用的字段Thread都可以进行GC.Thread完成后进行GC 并且是GC'd.startThread()堆栈的本地和分配.当startThread()方法完成并重复使用堆栈时,它将被覆盖.startThread()在堆上本地并分配的.它不能被线程使用,因为它不是final.startThread()完成后可以GC'd .startThread()在堆上本地并分配的.这是final因为它可以被线程使用,但事实并非如此.startThread()完成后可以GC'd .startThread()在堆上本地和分配的.这是final并且由线程使用.它只能在两个后GC'd startThread()方法完成,并在Runnable与Thread被GC'd.Runnable,在堆上作为Runnable匿名类的一部分进行分配.它可以在Runnable完成之后进行GC Runnable并且Thread是GC'd.Runnable,在堆内分配.它可以在Runnable完成之后进行GC Runnable并且Thread是GC'd.run()方法内部的本地字段,并在新线程的堆栈上分配.当run()方法完成并重复使用堆栈时,它将被覆盖.run()方法内部的一个局部字段,并在堆上分配.run()方法完成后可以进行GC'd .baz()方法内部的本地字段,并在新线程的堆栈上分配.当baz()方法完成并重复使用堆栈时,它将被覆盖.baz()方法内部的局部字段,并在堆上分配.baz()方法完成后可以进行GC'd .结合其他笔记:
startThread()完成就可以进行GC .将Runnable和所有与它相关的变量,可以再GC'd为好.final long varX声明startThread()并使用了原语,那么它必须在堆而不是堆栈上分配.当startThread()完成它仍然在使用.