@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 не дотянется, типа кучи больших объектов.
  • Вопрос задан
  • 940 просмотров
Пригласить эксперта
Ответы на вопрос 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, т.к. на них неявно появляются указатели.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы