12

我了解ABA问题。但我无法理解的是:他们说在具有自动垃圾收集的语言中它可能不会表现出来。所以我的问题是:

  • 自动垃圾收集如何防止 ABA 问题的发生?
  • 在java中是否有可能,如果可以,如何?
  • 是否有可能防止这种情况发生?
4

4 回答 4

9
  • 启用自动垃圾回收后,任何两个对象都不能被分配同一个引用并同时共存,这是因为只要引用计数大于 0,引用本身就不会被释放和重用.

    因此,当某人仍然拥有旧参考时,您不能将参考内容“切换”为“指向”不同的对象。

于 2013-10-29T16:27:06.103 回答
2

ABA 问题与垃圾收集正交。例如,应用程序可以将对象从链接列表移动到空闲列表,然后立即重新使用它们。因此,对象在重新使用之前从未真正释放。话虽如此,ABA问题可能以这种方式发生:

Thread1:
    prevHead = head;

Thread2:
    prevHead = head;
    newHead = getFromFreeList();
    if (cas(&head, prevHead, newHead)) addToFreeList(prevHead);

Thread3:
    prevHead = head;
    newHead = getFromFreeList(); // Get the same object 'released' by Thread2
    cas(&head, prevHead, newHead) // succeeds and put back what was removed by Thread2

Thread1:
    newHead = getFromFreeList();
    if (cas(&head, prevHead, newHead)) addToFreeList(prevHead);
    // CAS will succeed although it shouldn't since there were
    // a modification on the head done by 'Thread3' in between.
于 2014-09-26T05:00:28.947 回答
1

自动垃圾收集如何防止 ABA 问题的发生? 请参阅 Herlihy Shavit 的“多处理器编程艺术”。Quote:它(ABA问题)经常出现,尤其是在动态内存算法中。

所以当然 ABA 问题可以出现在 Java 中,但是由于在大多数情况下,问题出现在动态内存算法中,并且您不会经常在 java 中实现此类算法,因此您不会经常在 java 中看到此错误。

在java中是否有可能,如果可以,如何? “多处理器编程的艺术”一书在 java 中给出了一个与无锁并发队列的内存回收相关的问题的示例。

是否有可能防止这种情况发生?Quote:避免 ABA 通过测试两个时间点的值是否相同,但这些点之间的值是否曾经改变。一种方法是使用 AtomicStampedReference

于 2013-10-30T19:19:38.050 回答
1

在“多处理器编程的艺术”一书中,作者讨论了程序员可能希望在 Java 中实现他们自己的资源池(例如,列表节点池)的情况。然后,直接管理池的程序员绕过垃圾收集,从而提高了性能。尽管如此,必须小心避免ABA问题。

以下是 Java 中用于内存管理的 Java 代码的核心:

ThreadLocal<Node> freeList = new ThreadLocal<Node>() {
    protected Node initialValue() { return null; };
};

LockFreeQueueRecycle.java 的完整代码可在此处获得:

http://booksite.elsevier.com/9780123705914/exercises/07~Chapter_10.zip

请参阅第 10 章的幻灯片和代码:

http://booksite.elsevier.com/9780123705914/?ISBN=9780123705914

于 2018-06-18T20:02:35.823 回答