При вызове A (x) x гарантированно сохраняется до конца A - поскольку B использует тот же параметр.
Это утверждение неверно. Предположим, что метод A всегда вызывает исключение. Джиттер может знать, что B никогда не будет достигнут, и, следовательно, x может быть немедленно освобожден. Предположим, что метод A входит в безусловный бесконечный цикл после последней ссылки на x; Опять же, дрожание может знать, что с помощью статического анализа определить, что x никогда больше не будет ссылаться, и запланировать его очистку. Я не знаю, действительно ли джиттер выполняет эти оптимизации; они кажутся хитрыми, но они законны.
Может ли эта оптимизация (а именно, выполнить раннюю очистку ссылки, которая нигде не используется) на самом деле JITter?
Да, и на практике это делается. Это не наблюдаемый побочный эффект.
Это оправдано разделом 3.9 спецификации, которую я привожу для вашего удобства:
Если к объекту или какой-либо его части нельзя получить доступ любым возможным продолжением выполнения, кроме запуска деструкторов, объект считается больше не используемым, и он становится пригодным для уничтожения. Компилятор C # и сборщик мусора могут анализировать код, чтобы определить, какие ссылки на объект могут быть использованы в будущем. Например, если локальная переменная, которая находится в области видимости, является единственной существующей ссылкой на объект, но на эту локальную переменную никогда не ссылаются при любом возможном продолжении выполнения с текущей точки выполнения в процедуре, сборщик мусора может (но не требуется) обрабатывать объект как более не используемый.
Может ли оптимизация, выполняемая компилятором C # или JITter, иметь видимые побочные эффекты?
На ваш вопрос ответили в разделе 3.10 спецификации, которую я привожу здесь для вашего удобства:
Выполнение программы на C # продолжается
так что побочные эффекты каждого
выполняющийся поток сохраняется в
критические точки выполнения.
сторона
эффект определяется как чтение или запись
летучего поля, запись в
энергонезависимая переменная, запись в
внешний ресурс, и бросание
исключение.
Критическое исполнение
точки, в которых порядок этих
побочные эффекты должны быть сохранены
ссылки на изменчивые поля, операторы блокировки,
и создание и завершение потока.
Среда исполнения свободна для
изменить порядок выполнения C #
программа при условии соблюдения следующего
ограничения:
Зависимость данных
хранится в потоке
выполнение. То есть ценность каждого
переменная вычисляется так, как будто все
операторы в потоке были выполнены
в оригинальном программном порядке.
Правила порядка инициализации
сохранились.
The
порядок побочных эффектов сохраняется
в отношении изменчивых чтений и
пишет.
Кроме того,
среда выполнения не должна
оценивать часть выражения, если оно
можно сделать вывод, что это выражение
значение не используется и что не нужно
побочные эффекты производятся (в том числе
любой вызванный вызовом метода или
доступ к изменчивому полю).
Когда
выполнение программы прерывается
асинхронное событие (например,
исключение, выброшенное другим потоком),
не гарантируется, что
наблюдаемые побочные эффекты видны в
оригинальная программа заказа.
От второго к последнему абзацу я считаю, что вас больше всего беспокоит; то есть, какую оптимизацию разрешено выполнять среде выполнения для воздействия на наблюдаемые побочные эффекты? Среде выполнения разрешено выполнять любую оптимизацию, которая не влияет на наблюдаемый побочный эффект.
Обратите внимание, что, в частности, зависимость данных сохраняется только в пределах потока выполнения. Зависимость данных не гарантированно сохраняется при наблюдении из другого потока выполнения.
Если это не отвечает на ваш вопрос, задайте более конкретный вопрос . В частности, потребуется тщательное и точное определение «наблюдаемого побочного эффекта», чтобы ответить на ваш вопрос более подробно, если вы не считаете приведенное выше определение соответствующим вашему определению «наблюдаемого побочного эффекта».