Примеры из книги
От: HomoHabilis  
Дата: 19.03.15 08:49
Оценка: +1
Уж извините за глупый вопрос, перечитываю тут Рихтера там такой код
internal static class FixedStatement
{
  unsafe public static void Go()
  {
    // Allocate a bunch of objects that immediately become garbage
    for (Int32 x = 0; x < 10000; x++) new Object();

    IntPtr originalMemoryAddress;
    Byte[] bytes = new Byte[1000];   // Allocate this array after the garbage object

    // Get the address in memory of the Byte[]
    fixed (Byte* pbytes = bytes) { originalMemoryAddress = (IntPtr)pbytes; }

    // Force a collection; the garbage objects will go away & the Byte[] might be compacted
    GC.Collect();
    GC.WaitForPendingFinalizers();

    // Get the address in memory of the Byte[] now & compare it to the first address
    fixed (Byte* pbytes = bytes)
    {
      Console.WriteLine("The Byte[] did{0} move during the GC",
         (originalMemoryAddress == (IntPtr)pbytes) ? " not" : null);
    }
  }
}

и текст из книги

Using C#’s fixed statement is more efficient that allocating a pinned GC handle. What happens
is that the C# compiler emits a special “pinned” flag on the pbytes local variable. During a garbage
collection, the GC examines the contents of this root, and if the root is not null, it knows not to
move the object referred to by the variable during the compaction phase. The C# compiler emits IL to
initialize the pbytes local variable to the address of the object at the start of a fixed block, and the
compiler emits an IL instruction to set the pbytes local variable back to null at the end of the fixed
block so that the variable doesn’t refer to any object, allowing the object to move when the next
garbage collection occurs.

Ведь переменная фиксируется и не перемещается при сборке только внутри fixed блока.
что то как то пример кажется не совсем актуален что ли, может интереснее было бы так:
internal static class FixedStatement
{
  unsafe public static void Go()
  {
    // Allocate a bunch of objects that immediately become garbage
    for (Int32 x = 0; x < 1000000; x++) new Object();

    IntPtr originalMemoryAddress;
    Byte[] bytes = new Byte[1000];   // Allocate this array after the garbage object

    // Get the address in memory of the Byte[]
    fixed (Byte* pbytes = bytes) {
      originalMemoryAddress = (IntPtr)pbytes; //}

    // Force a collection; the garbage objects will go away & the Byte[] might be compacted
    GC.Collect();
    GC.WaitForPendingFinalizers();

    // Get the address in memory of the Byte[] now & compare it to the first address
    //fixed (Byte* pbytes = bytes)
    //{
      Console.WriteLine("The Byte[] did{0} move during the GC",
         (originalMemoryAddress == (IntPtr)pbytes) ? " not" : null);
    }
  }
}



[/cs]
Re: Примеры из книги
От: Iso12  
Дата: 19.03.15 11:37
Оценка:
Здравствуйте, HomoHabilis, Вы писали:

В этом примере как раз наглядно показано, что может произойти если не корректно использовать fixed блок и IntPtr.
По моему очень хороший пример.
Re[2]: Примеры из книги
От: HomoHabilis  
Дата: 19.03.15 12:15
Оценка:
Здравствуйте, Iso12, Вы писали:

I>Здравствуйте, HomoHabilis, Вы писали:


I>В этом примере как раз наглядно показано, что может произойти если не корректно использовать fixed блок и IntPtr.

I>По моему очень хороший пример.

просто я сам засомневался что понимаю правильно, поэтому и спросил здесь
т.е. первый пример — неправильное использование fixed
второй — правильное, так?

и еще момент хз может от размера памяти зависит бюджет нулевого поколения но на моей машине этого
// Allocate a bunch of objects that immediately become garbage
    for (Int32 x = 0; x < 10000; x++) new Object();


мало что бы сборка запустилась(ну т.е. удалился бы мусор и живые объекты скомпоновались бы)
надо как минимум два нуля приписать
Отредактировано 19.03.2015 12:17 ГАИ . Предыдущая версия .
Re[3]: Примеры из книги
От: Iso12  
Дата: 19.03.15 17:19
Оценка:
Здравствуйте, HomoHabilis, Вы писали:


HH>просто я сам засомневался что понимаю правильно, поэтому и спросил здесь

HH>т.е. первый пример — неправильное использование fixed
HH>второй — правильное, так?

Всё зависит от контекста, в котором этот пример приведён. Если это "Автоматическое управление памятью", то тут наглядно показаны процессы, которые происходят при работе GC и этот пример идеально подходит для этого.


HH>и еще момент хз может от размера памяти зависит бюджет нулевого поколения но на моей машине этого

HH>
HH>// Allocate a bunch of objects that immediately become garbage
HH>    for (Int32 x = 0; x < 10000; x++) new Object();
HH>


HH>мало что бы сборка запустилась(ну т.е. удалился бы мусор и живые объекты скомпоновались бы)

HH>надо как минимум два нуля приписать

На сколько я понимаю, сборка мусора должна произойти в любом случае при прямом вызове GC, оптимизация зависит от состояния памяти (могу и ошибаться).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.