据说Java允许并行运行多个线程。它还说对象创建很便宜,所以我必须总是喜欢创建新对象来重用它们。但是,据我所知,对象是在全局范围内创建的(成为GC的主体)。现在,奇迹出现了,当任何线程创建对象时,并行性会停止吗?
AFAIK,非托管语言在线程堆栈上创建对象,以便线程独立运行。退出子程序范围后,它们全部被删除。也就是说,您无需将对象添加到全局列表中,并在稍后将机器停止GC。您可以使用Java中的Int / String类不可变对象执行相同操作,因为您无法引用创建循环依赖关系的其他对象,这需要GC进行清理。但是,afaik,Java中的程序出口没有清理任何东西。
答案 0 :(得分:2)
由于TLAB(线程局部分配缓冲区),大多数时候小对象的分配非常便宜。每个线程在Eden中都有一个特殊区域,用于称为TLAB的线程局部分配。
因此,只有在填充上一个TLAB时才需要分配新的TLAB。该同步是CAS操作,所以它非常快。
Eden Survivor 1/2
-------------------------------------------------
| T | | T | || | |
| L | | L | || | |
| A | | A | || | |
| B | | B | || | |
| | | | || | |
| 1 | | 2 | || | |
-------------------------------------------------
^ ^
| |
reserved for|thread-1 allocations
|
|
reserved for thread-2 allocations
此外,一些优化可以帮助您避免编译代码中的分配 - 转义分析和标量替换。在某些情况下,编译器可以通过将对象的所有字段放在堆栈上来消除分配。