簡體   English   中英

在Java中,如何刷新CPU內存緩存以便從RAM內存中檢索最新內存?

[英]In Java, how do I flush the CPU memory cache so it retrieves the latest from the RAM memory?

計算機具有RAM內存,但它也具有小巧,快速的CPU內存緩存。 Java內存模型保證在訪問具有volatile的變量時刷新CPU內存緩存,但由於我們僅在單個線程中的單個類中使用該volatile變量,因此不確定JIT是否只是優化它。

為了診斷一個bug(當我們在某個時刻調用Thread.sleep()足夠長時才會出現這個bug),我們需要能夠做這樣的事情(而不是sleep()):

System.clearCpuCache();

實現這種方法的最簡單,最可靠的方法是什么? 它應該保證它不會JIT優化緩存刷新。 我們只能在啟用JIT的情況下重現我們的錯誤,因此禁用JIT不是一種選擇。

你一般不能。 除性能外,緩存的存在對應用程序是透明的。 這也適用於多處理器系統,只要緩存系統是“緩存一致”,這實際上是當今使用的所有平台。

因此,你的錯誤在其他地方。

像volatile和synchronized塊這樣的東西不會影響緩存一致性本身,而是影響寄存器優化,使用原子指令(包括刷新存儲緩沖區,這與緩存不同!),等等。 這些是你應該看的東西(好吧,鑒於你的描述中缺乏細節,很難說,但作為第一個猜測..),而不是試圖刷新緩存。

訪問volatile變量應該繞過緩存,而不是刷新它。 因此清除緩存不應影響volatile的行為。 這個bug如何表現出來? 您是否在Thread.sleep()之后和同一個線程上看到過時的值? 很多年前,我為Java兼容性測試套件編寫了測試。 其中一個測試證明,volatile變量可以從緩存中讀取,而不是從主內存中讀取。 我想知道這個bug是否仍然存在。 請將詳細信息發送至rfq(at)list.ru,我將嘗試創建令人信服的測試。

我不確定這是否是這種情況(需要更多詳細信息!),但有一件事需要注意,如果你看到一個關於volatile的硬線程錯誤,那就是volatile不一定是原子的。

即你可能認為你已經更新了一個volatile變量並且新值應該是可見的,但實際上你並沒有因為完整更新沒有完成。

http://www.ibm.com/developerworks/java/library/j-jtp11234/

你試過AtomicInteger了嗎?

如果值始終由同一個線程更改/讀取,我無法看到如何從cpu緩存中獲取錯誤版本的volatile int。 也許嘗試打印出變量上每次讀/寫時哪個線程處於活動狀態,只是為了100%確定:

System.out.println(Thread.currentThread().getName());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM