2009-08-07 17 views
9

Estoy usando un std::deque para almacenar una cantidad bastante grande de objetos. Si elimino un montón de esos objetos, me parece que su uso de memoria no disminuye, de manera similar a std :: vector.¿Cómo liberar memoria de std :: deque?

¿Hay alguna manera de reducirlo? Sé que en un vector tienes que usar el "truco de intercambio", que supongo que también funcionaría aquí, pero prefiero evitarlo ya que requeriría copiar todos los elementos que quedan en el contenedor (y por lo tanto requiere que tengas suficiente memoria para almacenar cada objeto dos veces). No estoy íntimamente familiarizado con la implementación de deque, pero mi comprensión de esto es que podría ser posible lograr tal cosa sin muchas copias (mientras que con un vector claramente no lo es).

Estoy usando el VC++ (Dinkumware) STL, si eso hace la diferencia.

+2

¿Ha establecido que su implementación deque no está liberando bloques de memoria tan pronto como se eliminan suficientes elementos para vaciarlos? ¿O es que realmente quieres exprimir los últimos bytes reasignando el bloque en cada extremo? –

+0

Creo que sí, de una manera bastante difícil y rápida: agrego 100.000 elementos -> El uso de memoria es ~ 90 MB. Agrego otro 100,000 -> el uso de memoria es ~ 170MB. Elimino 100,000 elementos -> el uso de la memoria aún es ~ 170MB. Agregue otro 100,000 -> todavía 170. Supongo que 100,000 artículos es más que suficiente que tendría bloques vacíos que se liberarían si fuera necesario. – Peter

+5

¿Uso de memoria del proceso o uso de memoria de la colección? El hecho de que la colección libere la memoria no significa que vuelva al sistema operativo, así que trate de asignar 80MB de matriz de caracteres después de eliminar los elementos, y vea si el uso va a 250MB o permanece en 170. Disculpe si ya sabe todo esto cosas y lo han contabilizado, millones no lo harían. –

Respuesta

14

No hay forma de hacerlo directamente en std :: deque. Sin embargo, es fácil de hacer mediante el uso de un temporal (que es básicamente lo que ocurre en un std :: vector cuando se reduce su capacidad).

Aquí está un good article on std::deque, que lo compara con std :: vector. La parte inferior muestra una forma limpia de cambiar y reducir un vector, que funciona igual con deque.

+0

Gracias. Sospechaba que no podría haber ninguna forma de hacerlo, pero parece que debería ser posible ... Expliqué en la pregunta por qué estoy reacio a usar el intercambio en este caso, pero tal vez lo haga. tiene que mirarlo independientemente – Peter

+0

Peter: la mejor opción con el "intercambio" es usar elementos asignados en el montón. En ese caso, solo está haciendo una copia de las referencias, en lugar de una copia de todos los elementos más su memoria. Eso es bastante menor, por lo general. –

+0

El intercambio solo cambia los punteros internos del vector, no los elementos en sí mismos. – Karu

4

El tamaño de la memoria de una deque podría reducirse o no. Cuando y Cómo ocurre esto es específico de la implementación. Desafortunadamente no tienes mucho control manual sobre esto ya que losques carecen de capacidad() o reserva().

Sugeriría swap() si efectivamente detecta que la liberación de la memoria no se está realizando a su conveniencia.

un conocimiento íntimo de la gestión de memoria deque puede probablemente ser adquirida desde el sitio web Dikum (esta es su implementación actual, ¿verdad?)

1

std :: deque volverá a su memoria asignador. A menudo, este asignador no devolverá la memoria al sistema operativo. En tales casos, parece que la memoria no está "liberada". Los buenos detectores de fugas de memoria se cumplirán tan pronto como se devuelva la memoria al asignador, y comprenderán que no toda la memoria se libera al free().

3

Como añade información a este:

En C++ 0x/C++ 11, deque (y varios otros recipientes) tiene una nueva función llamada "shrink_to_fit" que eliminará los artículos en exceso y básicamente alinear capacidad() == size()

+0

capacidad() aún puede ser mayor que size() después de shrink_to_fit() - es una solicitud no vinculante; 'void shrink_to_fit() {}' es una implementación perfectamente legal, en realidad. Pero incluso con una buena implementación, la capacidad() puede ser mayor que el tamaño(), por ejemplo, si el contenedor tiene muy pocos elementos, aún podría valer la pena asignar más memoria. (Piense en contenedores vacíos) – Lrdx

Cuestiones relacionadas