¿Qué son los objetos clavados?

Estoy tratando de encontrar una pérdida de memoria usando el generador de perfiles de memoria de ants, y me he encontrado con un nuevo término:

Objetos fijados

¿Puede alguien darme una buena y simple explicación acerca de qué son estos objetos? ¿Cómo puedo identificar / desentrañar objetos y detectar quién fijó los objetos?

Gracias

Un objeto fijado es aquel que no puede moverse. El recolector de basura normalmente compacta la memoria porque mueve todos los objetos a “uno o más clústeres”. Esto es para crear grandes porciones de espacio libre.

Esto significa básicamente que si alguien más (fuera) tiene un puntero a la dirección de memoria de un objeto, esto puede apuntar a contenido aleatorio, a medida que el objeto se mueve.

Fijar un objeto le dice al GC que NO SE MUEVA. Esto normalmente es inútil y SÓLO tiene sentido cuando se trabaja con punteros, como cuando se utiliza PInvoke. En ocasiones, debe ingresar una dirección en una estructura (en el término de diseño de memoria), y si eso se implementa en una clase, debe anclarlo.

Para responder concreto:

  • No puedes descubrir quién anotó un objeto.
  • Pinning se hace con la statement FIJA. Esto solo está permitido en un código no seguro.

Comprobar:

http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

Un objeto anclado es aquel que no puede ser movido por el recolector de basura, lo que significa que su dirección debe mantenerse igual porque otra persona, por lo general un fragmento de código no administrado, depende de que el objeto esté en una dirección de memoria definida.

Por lo general, el recolector de basura tiene libertad para reubicar objetos en la memoria. En el código administrado, como el recolector de basura tiene la capacidad de acceder a todas las referencias, puede reasignar libremente un objeto a una ubicación diferente y luego actualizar todas las referencias a ese objeto para que el proceso sea transparente para el código en ejecución. De esta forma, el GC tiene la capacidad de organizar mejor la memoria del progtwig y compactarla si es necesario.

Cuando un objeto no gestionado está interactuando con su código (en secciones inseguras), puede surgir una situación en la que haya un puntero en alguna parte de una parte de su código, por ejemplo, en una parte de la memoria tratada en su código. una llamada COM externa. Esta memoria no se puede reasignar porque la llamada COM espera que el objeto esté en una dirección determinada y, por lo tanto, si se movió, el GC no tendría manera de notificar al objeto COM de ese cambio, lo que daría como resultado un acceso violación o peor.

Los objetos fijados se utilizan cuando se comunica con un código no administrado. En el código administrado, el recolector de basura puede mover libremente los bloques de memoria, ya que conoce todas las referencias al bloque de memoria y puede actualizarlos en consecuencia.

Cuando se comunica con un código no administrado (por ejemplo, Win-API), los punteros a los datos o los buffers a menudo se pasan como argumento. Si el recolector de basura fuera libre de mover esos datos, los punteros se volverían inválidos de repente. A medida que el puntero se transfiere a un código no administrado, el GC no puede actualizar el puntero, ni siquiera saber dónde se usa. Para evitar que la memoria se mueva y asegurarse de que los datos permanecen en el lugar conocido por el puntero del código no administrado, el objeto puede ser anclado .

La razón por la que podría anclar un objeto es si está realizando llamadas al código no administrado.

Cuando el recolector de basura se ejecuta, puede eliminar un objeto que ya no se necesita. Esto deja un “agujero” de espacio libre en el montón. El GC compacta el montón moviendo los objetos restantes para asegurarse de que el espacio libre esté en un bloque continuo (un poco como desfragmentar el disco duro).

También actualiza todas las referencias (en el código administrado) a cualquier objeto que se haya movido como parte de la compactación.

Si está trabajando con código no administrado (por ejemplo, algún C ++ externo) y le da un puntero a un objeto, no hay forma de que el GC le diga al código no administrado que el objeto se ha movido después de que se haya ejecutado. Por lo tanto, puede marcar el objeto que comparte con el código externo como fijado para que no tenga el problema de que el puntero se vuelva inválido.

Para fijar objetos, puede usar la palabra clave fija :

La instrucción fija evita que el recolector de basura reubique una variable movible. La statement fija solo está permitida en un contexto inseguro.

Un ejemplo que he visto antes es dividir un valor largo en bytes para que pueda codificarse en una clave de serie. Esto se hizo en un contexto inseguro para obtener el puntero. Los errores intermitentes comenzaron a ocurrir porque la recolección de basura ocurriría a mitad del proceso de obtener los bytes individuales. El valor se reubicaría y nos quedamos con la mitad de los bytes correctos, la mitad de los bytes de basura.

La solución para nosotros fue usar la clase BitConverter . Si observa el código subyacente de la clase BitConverter, verá que usa la palabra clave fija para fijar la matriz de bytes mientras obtiene los bytes de la variable.

Un objeto fijado es aquel que tiene una ubicación establecida en la memoria.

Normalmente, el recolector de basura compactará el montón administrado, que cambia la ubicación de los objetos en la memoria. Si tiene algún código no administrado que hace referencia a algún objeto C # que haya creado, es posible que desee poder hacer referencia a la ubicación de la memoria en forma absoluta. Fijar el objeto le permite hacer esto con certeza.

Puede crearlos usando la instrucción fixed : http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

lo obtuve de msdn “Un objeto fijado es uno que el recolector de basura no puede mover en la memoria”

http://msdn.microsoft.com/en-us/library/x2tyfybc(VS.71).aspx