简体   繁体   English

Java 非阻塞内存分配

[英]Java nonblocking memory allocation

I read somewhere that java can allocate memory for objects in about 12 machine instructions.我在某处读到 java 可以用大约 12 条机器指令为对象分配内存。 It's quite impressive for me.这对我来说印象非常深刻。 As far as I understand one of tricks JVM using is preallocating memory in chunks.据我了解,JVM 使用的技巧之一是分块预分配内存。 This help to minimize number of requests to operating system, which is quite expensive, I guess.这有助于最大限度地减少对操作系统的请求数量,我猜这是非常昂贵的。 But even CAS operations can cost up to 150 cycles on modern processors.但即使是 CAS 操作在现代处理器上也可能花费高达 150 个周期。

So, could anyone explain real cost of memory allocation in java and which tricks JVM uses to speed up allocation?那么,谁能解释一下 java 中内存分配的实际成本以及 JVM 使用哪些技巧来加速分配?

The JVM pre-allocates an area of memory for each thread (TLA or Thread Local Area). JVM 为每个线程预先分配一块内存区域(TLA 或线程局部区域)。 When a thread needs to allocate memory, it will use "Bump the pointer allocation" within that area.当线程需要分配内存时,它将在该区域内使用“Bump the pointer allocation”。 (If the "free pointer" points to adress 10, and the object to be allocated is size 50, then we just bump the free pointer to 60, and tell the thread that it can use the memory between 10 and 59 for the object). (如果“空闲指针”指向地址10,并且要分配的对象大小为50,那么我们只需将空闲指针撞到60,并告诉线程它可以为对象使用10到59之间的内存) .

The best trick is the generational garbage-collector.最好的技巧是分代垃圾收集器。 This keeps the heap unfragmented, so allocating memory is increasing the pointer to the free space and returning the old value.这可以保持堆不碎片化,因此分配内存会增加指向可用空间的指针并返回旧值。 If memory runs out, the garbage-collection copy objects and creates this way a new unfragmented heap.如果内存耗尽,垃圾收集复制对象并以这种方式创建一个新的未碎片堆。

As different threads have to synchronize over the pointer to the free memory, if increasing it, they preallocate chunks.由于不同的线程必须同步指向空闲内存的指针,如果增加它,它们会预先分配块。 So a thread can allocate new memory, without the lock.所以一个线程可以分配新的内存,没有锁。

All of this is explained in more detail here: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html所有这些都在这里有更详细的解释: http : //java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html

There is no single memory allocator for the JVM. JVM 没有单一的内存分配器。 IIRC Sun's JVM and IBM's managed memory differently. IIRC Sun 的 JVM 和 IBM 的托管内存不同。 However generally the way the JVM will operate is that it will initially allocate one piece of memory, this segment will be small enough to live in the processors cache making all access to this extremely fast.然而,通常 JVM 的操作方式是它最初会分配一块内存,该段将小到足以存在于处理器缓存中,从而使所有访问都非常快。

As the application creates objects, the objects will take memory from within this segment.当应用程序创建对象时,对象将从该段中获取内存。 The object allocation within the segment is simply pointer arithmetic.段内的对象分配只是指针运算。

Initially the offset address into the freshly minted segment will be zero.最初,新生成的段的偏移地址为零。 The first object allocated will have an 'address' (actually an offset into the segment) of zero.分配的第一个对象的“地址”(实际上是段的偏移量)为零。 When you allocate object then the memory manager will know how big the object is, allocate that much space within the segment (16 bytes say) and then increment it's "offset address" by that amount meaning that memory allocation is blindingly fast, it's just pointer arithmetic.当您分配对象时,内存管理器将知道对象有多大,在段内分配那么多空间(例如 16 字节),然后将它的“偏移地址”增加该数量,这意味着内存分配非常快,它只是指针算术。

Sun have a whitepaper here Memory Management in the JavaHotSpot™ Virtual Machine and IBM used to have a bunch of stuff on ibm.com/developerworks Sun 有一份白皮书JavaHotSpot™ 虚拟机中的内存管理,IBM 曾经在 ibm.com/developerworks 上有很多东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM