почему объект блокировки использует шаблон смещения, но уже заблокирован с помощью тонкой блокировки - PullRequest
1 голос
/ 31 марта 2020

Я читаю исходный код, чтобы выяснить, как работает блокировка смещения. У меня есть вопрос о «массовых ребиа», которые произошли, когда количество отозванных экземпляров конкретного типа данных. и это увеличило бы поле эпохи в классе , чтобы сделать недействительными ранее удержанные смещения, облегчает массовую передачу владения смещением из одного потока в другой.

, и этот код следует, он был записан в файле biasedLocking. cpp:

for (; JavaThread *thr = jtiwh.next(); ) {
      GrowableArray<MonitorInfo*>* cached_monitor_info = get_or_compute_monitor_info(thr);
      for (int i = 0; i < cached_monitor_info->length(); i++) {
        MonitorInfo* mon_info = cached_monitor_info->at(i);
        oop owner = mon_info->owner();
        markOop mark = owner->mark();
        if ((owner->klass() == k_o) && mark->has_bias_pattern()) {
          // We might have encountered this object already in the case of recursive locking
          assert(mark->bias_epoch() == prev_epoch || mark->bias_epoch() == cur_epoch, "error in bias epoch adjustment");
          owner->set_mark(mark->set_bias_epoch(cur_epoch));
        }
      }
    }

исходный код здесь . похоже, что все записи блокировки, которые заблокировали класс объекта, равны классу текущего объекта obj и все еще смещены. если какая-либо запись блокировки существует, ее владелец (объект блокировки) должен быть заблокирован с помощью облегченной блокировки (тонкой блокировки) потоком, что означает, что он должен был использовать блокировку смещения и отозван текущим владельцем, так почему этот код может найти блокировку объект использует шаблон смещения, но уже заблокирован с помощью тонкой блокировки?

обновлено в 2020/04/02

я пишу код для проверки:

package tech.lovelycheng.learning.javalang.jvmtest;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.*;

import static java.lang.System.err;

public class BIASREVOKEDANDREBIASEDTest {

private static final Unsafe U;
private static final long OFFSET = 0L;

static {

    try {
        Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
        unsafe.setAccessible(true);
        U = (Unsafe) unsafe.get(null);
    } catch (Exception e) {
        throw new IllegalStateException(e);
    }
}

public static void main(String[] args) throws ExecutionException, InterruptedException {
    ExecutorService threadPoolExecutor = Executors.newSingleThreadExecutor();

    Monitor monitor = new Monitor();

    synchronized (monitor) {

        err.println("monitor header: " + printBinaryHeader(monitor));
        //reach biasedLockingBulkRebiasThreshold
        for (int i = 0; i < 5; i++) { // to bulk rebias
            Monitor s = new Monitor();

            synchronized (s) {

            }

            threadPoolExecutor.submit(() -> {
                synchronized (s) {

                }
                return null;
            }).get();
        }
    }

    err.println("monitor header: " + printBinaryHeader(monitor));// break point here

    ss(threadPoolExecutor, monitor);


    threadPoolExecutor.shutdown();


}

private static void ss(ExecutorService threadPoolExecutor, Monitor monitor) throws InterruptedException, ExecutionException {
    threadPoolExecutor.submit(() -> {
        synchronized (monitor) {
            err.println("expect 101 at low end  monitor header: " + printBinaryHeader(monitor));
        }
    }).get();
}

private static String printHeader(Object a) {
    int word = U.getInt(a, OFFSET);
    return Integer.toHexString(word);
}

private static String printBinaryHeader(Object a) {
    int word = U.getInt(a, OFFSET);
    return Integer.toBinaryString(word);
}


private static class Monitor {
    // mutex object

    public void fn() {
    }
}

}

что я вижу через hsdb:

enter image description here

em ... основной поток просто выйдите из монитора, и без разногласий он наверняка будет использовать блокировку смещения. почему в его стеке есть basicObjectMonitor?

опция my jvm

-XX:+UseBiasedLocking
-XX:BiasedLockingStartupDelay=0
-Xlog:biasedlocking=trace
-XX:BiasedLockingBulkRebiasThreshold=5
-XX:BiasedLockingBulkRevokeThreshold=20
-XX:+PrintSafepointStatistics
-XX:PrintSafepointStatisticsCount=1

версия моего jdk: 11.0.6

1 Ответ

0 голосов
/ 05 апреля 2020

first: MonitorObjectLock будет размещен в текущем кадре, независимо от типа блокировки, используемой объектом блокировки. при выходе из монитора смещенная блокировка освобождается, маркерное слово объекта блокировки не изменится, а стек потока-владельца сохраняет MonitorObjectLock, а его поле obj имеет значение NULL. Таким образом, «массовое ребайс» будет ребайзировать MonitorObjectLock в стеке, когда поток владеет другой смещенной блокировкой (не освобождает и obj не имеет нулевого значения, и он смещен) пытается владеть смещенной, но не имеющей обязательной блокировкой, и счетчик аннулирования достигает BiasedLockingBulkRebiasThreshold .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...