将本地内存刷新到全局内存意味着什么? [英] What does flushing thread local memory to global memory mean?

查看:79
本文介绍了将本地内存刷新到全局内存意味着什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道Java中volatile变量的目的是对其他线程立即可以看到对这些变量的写入。我也知道同步块的一个影响是将线程本地内存刷新到全局内存。

I am aware that the purpose of volatile variables in Java is that writes to such variables are immediately visible to other threads. I am also aware that one of the effects of a synchronized block is to flush thread-local memory to global memory.

我从来没有完全理解对'thread-的引用 - 在这种背景下的本地'记忆。我理解只存在于堆栈上的数据是线程本地的,但是当谈论堆上的对象时,我的理解变得模糊。

I have never fully understood the references to 'thread-local' memory in this context. I understand that data which only exists on the stack is thread-local, but when talking about objects on the heap my understanding becomes hazy.

我希望能得到以下几点的评论:

I was hoping that to get comments on the following points:


  1. 在具有多个处理器的计算机上执行时,是否刷新线程本地内存只是将CPU缓存刷新到RAM中?

  1. When executing on a machine with multiple processors, does flushing thread-local memory simply refer to the flushing of the CPU cache into RAM?

执行时单处理器机器,这是否意味着什么?

When executing on a uniprocessor machine, does this mean anything at all?

如果堆可能在两个不同的内存位置具有相同的变量(每个都通过一个不同的线程),在什么情况下会出现这种情况?这对垃圾收集有什么影响? VM有多么积极地做这种事情?

If it is possible for the heap to have the same variable at two different memory locations (each accessed by a different thread), under what circumstances would this arise? What implications does this have to garbage collection? How aggressively do VMs do this kind of thing?

(编辑:添加问题4)退出同步时刷新了哪些数据块?它是本地线程的一切吗?它只是在synchronized块内写的吗?

( adding question 4) What data is flushed when exiting a synchronized block? Is it everything that the thread has locally? Is it only writes that were made inside the synchronized block?

Object x = goGetXFromHeap(); // x.f is 1 here    
Object y = goGetYFromHeap(); // y.f is 11 here
Object z = goGetZFromHead(); // z.f is 111 here

y.f = 12;

synchronized(x)
{
    x.f = 2;
    z.f = 112;
}

// will only x be flushed on exit of the block? 
// will the update to y get flushed?
// will the update to z get flushed?


总的来说,我想要了解是否thread-local是指只有一个CPU可以物理访问的内存,或者VM是否有逻辑线程局部堆分区?

Overall, I think am trying to understand whether thread-local means memory that is physically accessible by only one CPU or if there is logical thread-local heap partitioning done by the VM?

任何指向演示文稿或文档的链接都会非常有帮助。我花时间研究这个,虽然我找到了很多不错的文献,但我还是无法满足我对不同情况的好奇心。线程本地内存的定义。

Any links to presentations or documentation would be immensely helpful. I have spent time researching this, and although I have found lots of nice literature, I haven't been able to satisfy my curiosity regarding the different situations & definitions of thread-local memory.

非常感谢。

推荐答案

你所谈论的同花顺被称为记忆障碍。这意味着CPU确保从其他CPU /内核也可以看到它所看到的RAM。它意味着两件事:

The flush you are talking about is known as a "memory barrier". It means that the CPU makes sure that what it sees of the RAM is also viewable from other CPU/cores. It implies two things:


  • JIT编译器刷新CPU寄存器。通常,代码可以保留CPU寄存器中的一些全局可见数据(例如,实例字段内容)的副本。从其他线程看不到寄存器。因此, synchronized 的一半工作是确保不维护这样的缓存。

  • The JIT compiler flushes the CPU registers. Normally, the code may kept a copy of some globally visible data (e.g. instance field contents) in CPU registers. Registers cannot be seen from other threads. Thus, half the work of synchronized is to make sure that no such cache is maintained.

synchronized 实现还执行内存屏障,以确保从当前内核对RAM的所有更改都传播到主RAM(或者至少所有其他内核都知道这一点core具有最新值 - 缓存一致性协议可能相当复杂。)

The synchronized implementation also performs a memory barrier to make sure that all the changes to RAM from the current core are propagated to main RAM (or that at least all other cores are aware that this core has the latest values -- cache coherency protocols can be quite complex).

第二项工作在单处理器上是微不足道的系统(我的意思是,具有单个CPU的系统具有单核)但是单处理器系统现在往往变得更加罕见。

The second job is trivial on uniprocessor systems (I mean, systems with a single CPU which has as single core) but uniprocessor systems tend to become rarer nowadays.

至于线程局部堆,这理论上可以可以完成,但通常不值得付出努力,因为没有任何东西可以用 synchronized 来刷新内存的哪些部分。这是带共享内存的线程模型的限制:所有内存应该被共享。在第一次遇到 synchronized 时,JVM应该将其所有线程局部堆对象刷新到主RAM。

As for thread-local heaps, this can theoretically be done, but it is usually not worth the effort because nothing tells what parts of the memory are to be flushed with a synchronized. This is a limitation of the threads-with-shared-memory model: all memory is supposed to be shared. At the first encountered synchronized, the JVM should then flush all its "thread-local heap objects" to the main RAM.

然而,Sun最近的JVM可以执行逃逸分析,其中JVM成功证明某些实例永远不会从其他线程中看到。这是典型的,例如,由 javac 创建的 StringBuilder 实例来处理字符串的连接。如果实例从未作为参数传递给其他方法,则它不会变为全局可见。这使得它有资格进行线程局部堆分配,或者甚至在适当的情况下,用于基于堆栈的分配。请注意,在这种情况下,没有重复;实例不在两个地方同时。只有JVM可以将实例保存在私有的地方,而不会产生内存障碍。

Yet recent JVM from Sun can perform an "escape analysis" in which a JVM succeeds in proving that some instances never become visible from other threads. This is typical of, for instance, StringBuilder instances created by javac to handle concatenation of strings. If the instance is never passed as parameter to other methods then it does not become "globally visible". This makes it eligible for a thread-local heap allocation, or even, under the right circumstances, for stack-based allocation. Note that in this situation there is no duplication; the instance is not in "two places at the same time". It is only that the JVM can keep the instance in a private place which does not incur the cost of a memory barrier.

这篇关于将本地内存刷新到全局内存意味着什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆