Java非阻塞内存分配

我在某处读到java可以为大约12个机器指令中的对象分配内存。 这对我来说非常令人印象深刻。 据我所知,JVM使用的一个技巧是以块的forms预分配内存。 这有助于最大限度地减少对操作系统的请求数量,这是非常昂贵的,我想。 但即便是CAS操作也可能在现代处理器上花费多达150个周期。

那么,有没有人可以解释java中内存分配的实际成本以及JVM用于加速分配的技巧?

JVM为每个线程(TLA或线程局部区域)预先分配一个内存区域。 当一个线程需要分配内存时,它将在该区域内使用“Bump the pointer allocation”。 (如果“自由指针”指向地址10,并且要分配的对象大小为50,那么我们只是将空闲指针碰到60,并告诉线程它可以使用10到59之间的内存作为对象) 。

最好的技巧是世代垃圾收集器。 这使堆保持未分段,因此分配内存会增加指向可用空间的指针并返回旧值。 如果内存耗尽,则垃圾收集复制对象并以此方式创建新的未碎片堆。

由于不同的线程必须通过指向可用内存的指针同步,如果增加它,它们会预先分配块。 所以一个线程可以分配新内存,而不需要锁定。

所有这些都在这里有更详细的解释: http : //java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

JVM没有单个内存分配器。 IIRC正确地说Sun的JVM和IBM的管理内存不同。 然而,一般来说,JVM的运行方式是它最初会分配一块内存,这个段足够小,可以存放在处理器缓存中,使得所有访问速度极快。

当您在应用程序内部创建对象时,对象将从此段中获取内存。 段内的对象分配只是指针算术。

最初,新鲜铸造段的偏移地址将为零。 分配的第一个对象将具有零的“地址”(实际上是段中的偏移量)。 当您分配对象时,内存管理器将知道对象有多大,在段内分配那么多空间(比如说16个字节),然后将它的“偏移地址”增加一定量,这意味着内存分配速度非常快,它只是指针算术。

Sun在这里有一份白皮书http://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf和IBM过去在ibm.com/developerworks上有很多东西