@SergeySerge11

Как записать управляемый объект делегата, в неуправляемую память, или какие есть решения?

Вот есть код, там компилятор пишет предупреждение
"Это принимает адрес или получает размер, объявляет указатель на управляемый тип."
Что значит вроде понятно, А как исправить.
Есть такая структура, которая имеет поле Делегата,
Объекты этой структуры будут в неуправляемой памяти, То есть зафиксированы.
A* data=NativeMemory.Alloc(1000); Мо
У структуры есть поле управляемого типа, которое Слетает в случайный момент времени, как исправить или по другому как-то делать
Как можно зафиксировать Массив или делегат в памяти GCHandle не работает. почему-то или как разместить объект класса в неуправляемой памяти. Может есть другие решения?


public struct A
   { // еще 1000 полей
     public unsafe Fun  func; 
   public unsafe A* Next; //  должно быть такое поле, которое требует условия фиксации
      // Но может есть другие способы, не используя классы?
   }
 public delegate int Fun(int a,int b);   
  public static unsafe A* Create(Fun[] funces,int n = 1)
  {
      unsafe
      { 
          //funces  как зафиксировать в памяти этот массив. Или какие есть варианты 
          A* arr = (A*)NativeMemory.Alloc((nuint)(1 * sizeof(A)));
          funces[0] = (int a, int b) => a + b;
          var a = (A*)arr + 0;
          a->func = funces[0];
          return arr;
      } 
  }

Самое что непонятное. хоть вопрос на что где когда отправляй, почему то ломается то нет. Вот часа 2 назад этот код ломался, ничего не изменил, работает.
void fun(){
 int n = 1;
 var funces = new Fun[n];
 var arr = Create(funces);
  
 int res = 0;
 {

     for (int j = 0; j < 500000000; j++)
     {
         for (int i = 0; i < n; i++)
         { 
               if ((arr + i)->func != funces[0])
               {
                       // когда-то это поле слетает, Как сделать что бы (arr + i)->func  всегда      
                             // указывал на место в памяти массива делегатов? Или какие есть другие решения
                        Console.WriteLine("!!!!!!!!!!!!!! ");
              }
               res += (arr + i)->func(i, j); 
         } 
     }
 }

Какие есть решения? Или все по другому надо, но точно что, мне нужен массив структур в зафиксированной памяти
Вот я не понимаю, типа почему просто нельзя было сделать метод который запишет объект подальше от сборщика мусора, или почему Pinned объекты записываются где попало, замедляют работу сборщика, А не в отдельном блоке, куда GC не дотянется, типа кучи больших объектов.
  • Вопрос задан
  • 948 просмотров
Пригласить эксперта
Ответы на вопрос 1
AshBlade
@AshBlade Куратор тега C#
Просто хочу быть счастливым
Объекты этой структуры будут в неуправляемой памяти, То есть зафиксированы.

Неуправляемые объекты не подвергаются процессу сбора мусора - они вообще не проверяются.
Вот и происходит следующее:
1. Имеется массив объектов неуправляемой памяти
2. В каждом объекте имеется ссылка на объект управляемой памяти
3. GC запускается и т.к. неуправляемые объекты не проверяются, то объекты на которые ссылаются неправляемые исчезают, т.к. ссылок на них, возможно, больше не осталось.

Попробуй:
- Вызвать GC.KeepAlive на ссылках управляемой памяти (кол-беках)
var funces = new Fun[];
// Код
GC.KeepAlive(funces);

- Либо сохраняй массив объектов управляемой памяти вместе с целевым массивом, чтобы переменная с этим массивом хранилась в этом же методе и на нем вызови GC.KeepAlive (иначе область видимости ограничивается методом, в котором они создались). Примерно так:
var (arr, managedObjects) = Create(funces);
// Код
GC.KeepAlive(managedObjects);

- Либо, попробуй перед началом работы метода запрещать сборку мусора - GC.TryStartNoGCRegion/GC.EndNoGCRegion

Самое что непонятное. хоть вопрос на что где когда отправляй, почему то ломается то нет.

Во-первых, работа GC не детерминирована - он может запуститься в любой момент.
Во-вторых, DEBUG или RELEASE режимы компиляции добавляют различные оптимизации и т.д. в процесс работы.
В-третьих, при подключенном дебагере все локальные переменные не будут собраны GC, т.к. на них неявно появляются указатели.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы