Pregunta

Me gustaría convertir un archivo en la memoria usando la función mmap y me gustaría saber si la cantidad de memoria virtual en la plataforma actual es suficiente para convertir un archivo enorme. Para un sistema de 32 No puedo mapear archivo de más de 4 Gb.
Sería std::numeric_limits<size_t>::max() dame la cantidad de memoria direccionable o hay cualquier otro tipo que debería probar (off_t o alguna otra cosa)?

Como Lie Ryan ha señalado en su comentario de la "memoria virtual" que aquí se utilizan mal. La pregunta, sin embargo, sostiene: hay un tipo asociado con un puntero y tiene el valor máximo que define el límite superior de lo que pueda posiblemente dirección en su sistema. ¿Cuál es este tipo? Es size_t o tal vez ptrdiff_t?

¿Fue útil?

Solución

size_t sólo está obligado a ser lo suficientemente grande para almacenar el objeto más grande contigua única posible. Eso pueden no ser el mismo que el tamaño del espacio de direcciones (en sistemas con un modelo de memoria segmentada, por ejemplo)

Sin embargo, en plataformas comunes con un espacio de memoria plana, los dos son iguales, y por lo que puede salir con el uso size_t en la práctica si se conocen la CPU de destino.

De todos modos, esto no os ha dicho nada útil. Claro, una CPU de 32 bits tiene un espacio de memoria de 4 GB, y así size_t es un entero sin signo de 32 bits. Pero eso no dice nada acerca de cuánto puede destinar. Una parte del espacio de memoria es utilizada por el sistema operativo. Y algunas partes ya son utilizados por su propia aplicación:. Para mapear el ejecutable en la memoria (así como cualquier bibliotecas dinámicas se puede usar), para la pila de cada hilo, la memoria asignada en el montón y así sucesivamente

Así que no, trucos tales como tomar el tamaño de size_t te dice un poco sobre el espacio de direcciones que se está ejecutando en, pero nada muy utilizable. Usted puede pedir al sistema operativo la cantidad de memoria está en uso por su proceso y otras métricas, pero una vez más, que en realidad no le ayuda mucho. Es posible que un proceso para utilizar sólo un par de megabytes, pero tienen que extiende a lo largo de tantos pequeños asignaciones que es imposible encontrar un bloque contiguo de memoria mayor que 100 MB, por ejemplo. Y así, en una máquina de 32 bits, con un proceso que utiliza casi sin memoria, que sería poco probable que tal asignación. (E incluso si el sistema operativo tenía una API WhatIsTheLargestPossibleMemoryAllocationICanMake() mágico, que Todavía no le serviría. Se le diría lo que necesitaba desde hace un momento . Usted no tienen ninguna garantía que la respuesta seguiría siendo válida en el momento en que ha intentado asignar el archivo.

Así que en realidad, lo mejor que puede hacer es intente para correlacionar el archivo y ver si se produce un error.

Otros consejos

Hola se puede utilizar GlobalMemoryStatusEx y VirtualQueryEx si la codificación en Win32

La cosa es que el tamaño de un puntero le dice nada acerca de cuánto de ese "espacio de direcciones" es en realidad a su disposición, es decir, se puede asignar como un solo trozo contiguo.

Está limitado por:

  • el sistema operativo. Se puede elegir sólo a hacer un subconjunto de la teoría-posible rango de direcciones disponibles para usted, porque se necesita memoria asignable para fines OS-propios (como, por ejemplo, haciendo que la tarjeta gráfica uso de este dispositivo visible, y por supuesto para su uso por el propio sistema operativo ).
  • límites configurables. En Linux / UNIX, el "ulimit" resp comando. setrlimit () llamada al sistema permite limitar el tamaño máximo del espacio de direcciones de una aplicación de diversas maneras, y Windows tiene opciones similares a través de los parámetros de registro.
  • la historia de la aplicación. Si la aplicación utiliza la asignación de memoria extensivamente, el espacio de direcciones puede fragmentar limitar el tamaño máximo de direcciones virtuales contiguas "disponible".
  • la plataforma de hardware. Algunas CPUs tienen espacios de direcciones con "agujeros"; un ejemplo de ello es de 64 bits x86, donde los punteros sólo son válidos si están entre 0x0..0x7fffffffffff o 0xffff000000000000 y 0xffffffffffffffff. Es decir. usted tiene 2x128TB en lugar de la 16EB completa. Piense en ello como de 48 bits "firmado" punteros ...

Por último, no hay que confundir "memoria disponible" y "espacio de direcciones disponibles". Hay una diferencia entre hacer un malloc (someBigSize) y un mmap (..., someBigSize, ...) ya que el primero podría requerir la disponibilidad de memoria física para dar cabida a la solicitud mientras que el segundo lo general sólo se requiere disponibilidad de una conexión suficientemente grande rango de direcciones.

Para las plataformas UNIX, parte de la respuesta es utilizar getrlimit (rlimit_as) ya que esto da el límite superior para la invocación actual de su aplicación - como se ha dicho, el usuario y / o administrador puede configurar esto. Tiene la garantía de que cualquier intento de mmap áreas más grandes de lo que se producirá un error.

Re reformuló su pregunta "límite superior de lo que pueda posiblemente dirección en su sistema", es algo engañoso; su arquitectura de hardware específica. Hay 64 bits por ahí arquitecturas (x64, SPARC) cuya MMU permite felizmente (uintptr_t) (- 1) como dirección válida, es decir, algo que puede asignar a la última página de un espacio de direcciones de 64 bits. Si el sistema operativo permite que una aplicación para hacerlo o no es más una cuestión completamente diferente ...

Para las aplicaciones de usuario, el "alta marca" no es (siempre) fijado a-priori. Es sintonizable en, por ejemplo, Solaris o Linux. Ahí es donde getrlimit (rlimit_as) entra en juego.

Tenga en cuenta que una vez más, por la especificación, no habría nada para evitar un funcionamiento nominal (raro) sistema para elegir, por ejemplo, poner pilas de aplicaciones y montones en las direcciones "baja", mientras que poner el código en las direcciones "altos", en una plataforma con agujeros de espacio de direcciones. Se necesitaría punteros de 64 bits completos allí, no puede hacerlas más pequeña, pero podría haber un número arbitrario de rangos "inaccesibles / inválido", que no están disponibles para su aplicación.

Puede intentar sizeof(int*). Esto le dará la longitud (en bytes) de un puntero en la plataforma de destino. Por lo tanto, se puede averiguar qué tan grande es el espacio direccionable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top