Как GC препятствует очистке вновь созданной памяти / объектов во время цикла GC (Java / C #) - PullRequest
0 голосов
/ 17 апреля 2019

Предположим, что мы берем пример кода, как показано ниже

class Employee 
{
    int id;
    String name;
}

Employee e = new Employee(1, "NewEmployee");

В приведенном выше коде я предполагаю, что сначала выделяется куча памяти для объекта Employee, а затем его ссылка присваивается ссылке на стек e.

Действительно ли вышеприведенное допустимо или здесь происходит что-то глубокое?

Если да, то давайте предположим, сразу после создания памяти в куче и непосредственно перед тем, как ее ссылка будет присвоена e, GC запускает и идентифицирует, что нет никаких ссылок на эту новую память кучи от корней GC.

  1. Будет ли GC очищать этот ресурс ?
  2. Есть ли способ, которым JVM / CLR обрабатывает эти сценарии и избегает такого рода повреждения памяти?

Пометка Java и C #, как я вижу, логика очистки в случае Mark и Sweep для Java и C # кажется почти одинаковой (по крайней мере, с точки зрения идентификации неиспользуемого объектаот корней и очистки).

1 Ответ

3 голосов
/ 17 апреля 2019

Затем предположим, что сразу после создания памяти в куче и непосредственно перед тем, как ее ссылка назначена для e, GC запускает и определяет, что нет никаких ссылок на эту новую память кучи из корней GC

Это неверное предположение, GC просто не пойдет в середине такого назначения.Очевидно, это было бы некорректным и опасным поведением.

И в более общем случае, когда методы JITtting вводят «безопасные точки», где GC может сработать. Это, как правило, вызовы под-методов, длинные циклы и другие (это строго зависит от реализации JIT).

Не уверен насчет JVM, но в случае CLR трудно увидеть такое «GCInfo» о безопасных точках, даже если вы возьмете сгенерированный код сборки (например,используя https://sharplab.io). Я не знаю ни одного инструмента, кроме WinDbg, чтобы увидеть его.

...