que - Cantidad máxima de memoria por proceso de Java en Windows?
que es maxpermsize (5)
Como se señaló en la pregunta mencionada en el comentario, hay un límite práctico, alrededor de 1200 MB.
Sin embargo, la situación que describes tiene más profundidad que el tamaño de la memoria pura.
Cuando lee datos binarios de 910 MB y crea objetos de red fuera de él (en lugar de simplemente mantener los datos como una matriz de bytes), termina consumiendo mucha más memoria que 910 MB. Una estimación razonable sería que la representación en memoria consumirá el doble de memoria, porque (1) cada objeto contiene un puntero adicional (a la clase del objeto); y (2) hay muchos datos de contabilidad. Por ejemplo, si usa un HashMap para administrar sus objetos, además de cada objeto, también asigna un objeto Map.Entry que puede consumir fácilmente 16 o 20 bytes (depende de la implementación).
Por otro lado, todavía hay esperanza: ¿realmente necesita mantener todos los 910 MB en la memoria? ¿No puedes simplemente construir algo que lea los datos de una manera perezosa? Combinado con WeakReferences, creo que puedes lograrlo.
En Windows de 32 bits, de forma predeterminada, cada aplicación puede usar hasta 2 GB de espacio de direcciones virtual. Supongo que esto hace que -Xmx2048M
. Sin embargo, si tiene más RAM instalada, puede aumentar el espacio de direcciones virtuales de hasta 3 GB mediante el uso de parámetros de tiempo de inicio.
En boot.ini, puede crear nuevas opciones de arranque como esta:
[boot loader]<br>
timeout=5<br>
default=multi(0)disk(0)rdisk(0)partition(1)/WINDOWS<br>
[operating systems]<br>
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Microsoft Windows XP Professional - magyar" /noexecute=optin /fastdetect /usepmtimer<br>
multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Microsoft Windows XP Professional - magyar 3GB" /noexecute=optin /fastdetect /usepmtimer /3GB /USERVA=2800<br>
Aquí ajustando el parámetro / USERVA = 2800, puede sintonizar su máquina. Pero tenga en cuenta que a algunas configuraciones no les gustan los valores altos en este parámetro: esperan choques.
No hay nada mejor que un experimento empírico para responder a tu pregunta. Escribí un programa Java y lo ejecuté mientras especificaba el indicador XMX (también usé XMS = XMX para forzar a la JVM a preasignar toda la memoria). Para proteger aún más contra las optimizaciones de JVM, he asignado activamente un número X de objetos de 10MB. Ejecuto una serie de pruebas en varias JVM que aumentan el valor de XMX junto con el aumento del número de MB asignados, en sistemas operativos de 32 bits diferentes que utilizan ambas JVM de Sun e IBM. A continuación, presentamos un resumen de los resultados:
Sistema operativo: Windows XP SP2, JVM: Dom 1.6.0_02, Tamaño máximo del almacenamiento dinámico: 1470 MB
Sistema operativo: Windows XP SP2, JVM: IBM 1.5, Tamaño máximo del almacenamiento dinámico: 1810 MB
Sistema operativo: Windows Server 2003 SE, JVM: IBM 1.5, Tamaño máximo del almacenamiento dinámico: 1850 MB
Sistema operativo: Linux 2.6, JVM: IBM 1.5, tamaño máximo de almacenamiento dinámico: 2750 MB
Aquí están los intentos de ejecución detallados junto con el código fuente auxiliar de la clase de asignación:
WinXP SP2, SUN JVM:
C:>java -version java version "1.6.0_02" Java(TM) SE Runtime Environment (build 1.6.0_02-b06) Java HotSpot(TM) Client VM (build 1.6.0_02-b06, mixed mode)
java -Xms1470m -Xmx1470m Class1 142 ... about to create object 141 object 141 created
C:>java -Xms1480m -Xmx1480m Class1 145 Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
WinXP SP2, IBM JVMC:>c:/ibm/jdk/bin/java.exe -version java version "1.5.0" Java(TM) 2 Runtime Environment, Standard Edition (build pwi32devifx-20070323 (if ix 117674: SR4 + 116644 + 114941 + 116110 + 114881)) IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223ifx-2007 0323 (JIT enabled) J9VM - 20070322_12058_lHdSMR JIT - 20070109_1805ifx3_r8 GC - WASIFIX_2007) JCL - 20070131
c:/ibm/jdk/bin/java.exe -Xms1810m -Xmx1810m Class1 178 ... about to create object 177 object 177 created
C:>c:/ibm/jdk/bin/java.exe -Xms1820m -Xmx1820m Class1 179 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1820M requested Could not create the Java virtual machine.
Win2003 SE, IBM JVMC:>"C:/IBM/java" -Xms1850m -Xmx1850m Class1 sleeping for 5 seconds. Done.
C:>"C:/IBM/java" -Xms1880m -Xmx1880m Class1 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate he ap. 1880M requested Could not create the Java virtual machine.
Linux 2.6, IBM JVM[root@myMachine ~]# /opt/ibm/java2-i386-50/bin/java -version java version "1.5.0" Java(TM) 2 Runtime Environment, Standard Edition (build pxi32dev-20060511 (SR2)) IBM J9 VM (build 2.3, J2RE 1.5.0 IBM J9 2.3 Linux x86-32 j9vmxi3223-20060504 (JIT enabled) J9VM - 20060501_06428_lHdSMR JIT - 20060428_1800_r8 GC - 20060501_AA) JCL - 20060511a
/opt/ibm/java2-i386-50/bin/java -Xms2750m -Xmx2750m Class1 270
[root@myMachine ~]# /opt/ibm/java2-i386-50/bin/java -Xms2800m -Xmx2800m Class1 270 JVMJ9VM015W Initialization error for library j9gc23(2): Failed to instantiate heap. 2800M requested Could not create the Java virtual machine.
Aquí está el código:
import java.util.StringTokenizer;
public class Class1 {
public Class1() {}
private class BigObject {
byte _myArr[];
public BigObject() {
_myArr = new byte[10000000];
}
}
public static void main(String[] args) {
(new Class1()).perform(Integer.parseInt(args[0]));
}
public void perform(int numOfObjects) {
System.out.println("creating 10 MB arrays.");
BigObject arr[] = new BigObject[numOfObjects];
for (int i=0;i <numOfObjects; i++) {
System.out.println("about to create object "+i);
arr[i] = new BigObject();
System.out.println("object "+i+" created");
}
System.out.println("sleeping for 5 seconds.");
try {
Thread.sleep(5000);
}catch (Exception e) {e.printStackTrace();}
System.out.println("Done.");
}
}
Para un archivo grande, sugiero que use un archivo mapeado de memoria. Esto no usa el espacio de montón (o muy poco) para que el tamaño máximo de almacenamiento dinámico no sea un problema en este caso.
Recientemente hemos migrado de Windows a Linux (debido a problemas de tamaño de VM).
He oído hablar de muchos números arrojados en el pasado para Windows VM size (1200, 1400, 1600, 1800). En nuestros Servidores de Windows (2003), en nuestro entorno, con nuestras aplicaciones , ... Nunca he utilizado con éxito más de 1280 MB. Más allá de eso, nuestra aplicación comenzó a exhibir problemas de GC y OOM.
Cada vez que obtuve una nueva versión de VM intenté cambiar el número y nunca varió.
Ahora tiene un archivo de 900 MB, ¿qué sucede si el archivo aumenta a 1300 MB? ¿Qué harás?
Tienes un número de opciones
- Puerto a Linux / Solaris. Esto solo necesita hardware / software y lo que a menudo es un simple ejercicio de portabilidad.
- Usa Windows de 64 bits. Sin embargo, esto puede no estar libre de problemas de GC: he oído hablar de diferentes historias con vms de 64 bits.
- Rediseñe la aplicación para procesar el archivo de forma diferente. ¿Puede dividir el archivo lógicamente de alguna manera, puede leer el archivo en fragmentos y procesarlo de manera diferente, etc.?
Otras personas que usan OpenMap deben haber encontrado este problema. ¿Puedes aprovechar su conocimiento y no reinventar ninguna rueda?