JVM 并行对象创建性能
JVM parallel object creation performance
据说Java允许运行多个线程并行。它还说创建对象很便宜,因此我必须始终更喜欢创建新对象而不是重用它们。但是,据我所知,对象是在全局范围内创建的(成为 GC 的主题)。现在,奇怪的是,当任何线程创建对象时,并行性是否停止?
AFAIK,非托管语言在线程堆栈上创建对象,以便线程保持 运行ning 独立。一旦您退出子程序范围,它们都会被删除。也就是说,您不需要将对象添加到全局列表中并稍后停止机器以对它们进行 GC。你可以对 Java 中的 Int/String-like 不可变对象做同样的事情,因为你不能引用其他创建循环依赖的对象,需要 GC 来清理。但是,afaik,在 Java 的过程出口处没有清理任何东西。
由于 TLAB(线程本地分配缓冲区),大多数时候小对象的分配非常便宜。每个线程在 Eden 中都有一个特殊区域,用于线程局部分配,称为 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
此外,一些优化可以帮助您避免编译代码中的分配 - 转义分析和标量替换。在某些情况下,编译器可以通过将对象的所有字段放在堆栈上来消除分配。
据说Java允许运行多个线程并行。它还说创建对象很便宜,因此我必须始终更喜欢创建新对象而不是重用它们。但是,据我所知,对象是在全局范围内创建的(成为 GC 的主题)。现在,奇怪的是,当任何线程创建对象时,并行性是否停止?
AFAIK,非托管语言在线程堆栈上创建对象,以便线程保持 运行ning 独立。一旦您退出子程序范围,它们都会被删除。也就是说,您不需要将对象添加到全局列表中并稍后停止机器以对它们进行 GC。你可以对 Java 中的 Int/String-like 不可变对象做同样的事情,因为你不能引用其他创建循环依赖的对象,需要 GC 来清理。但是,afaik,在 Java 的过程出口处没有清理任何东西。
由于 TLAB(线程本地分配缓冲区),大多数时候小对象的分配非常便宜。每个线程在 Eden 中都有一个特殊区域,用于线程局部分配,称为 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
此外,一些优化可以帮助您避免编译代码中的分配 - 转义分析和标量替换。在某些情况下,编译器可以通过将对象的所有字段放在堆栈上来消除分配。