[RESOLVIDO] JVM Overhead

Bom dia!
Estou em um desafio do livro da caelum que pergunta o seguinte:
O que acontece se acabar a memória da java virtual machine? Como forçar isso?

Eu pesquisei no fórum e só consegui resultados para desalocar a minha intenção aqui seria o contrário, alguém pode me passar algum código que faça isso (se possível que gaste até a memória virtual aquela que usa do hd quando acaba a ram) e explicar que danos isso pode causar?

Eu axo que vc vai ter que estudar sobre a coleta de lixo do java.

[quote=Onimatsu]Bom dia!
Estou em um desafio do livro da caelum que pergunta o seguinte:
O que acontece se acabar a memória da java virtual machine? Como forçar isso?[/quote]
A JVM finaliza. Uma maneira fácil de forçar isso é usar uma recursão infinita gerando um StackOverflowError.

[code]public static void main( String[] args ) {
foo();
}

public static void foo() {
foo();
}[/code]

Quem controla a memória virtual é o SO, não a JVM. Para conseguir um erro dessas proporções vc teria que fazer algo realmente errado em alguma linguagem que você tenha controle maior sobre o SO e a máquina, como C ou C++. Se vc quer lotar um HD não precisa tentar gastar memória virtual. Basta vc criar um loop infinito que cria arquivos em alçgum diretório da máquina. Pode demorar, mas uma hora o HD vai ficar lotado :smiley:

Qnd acabar a memória da JVM a única coisa que acontecerá é uma exceção do tipo java.lang.OutOfMemoryError: Java heap space

Lembrando que essa e a memoria da JVM, que não utiliza toda a RAM do pc.
Na verdade, acho q nenhum SO deixa vc usar toda a RAM do pc.

Exemplo pedido.

[code]
public class Aa {

/**
 * @param args
 */
public static void main(String[] args) {
	List<Integer> lista = new ArrayList<Integer>();
	while (true){
		lista.add(new Integer(33));
	}

}

}[/code]

ou

public class Aa {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		boolean loop = true; 
		List<Integer> lista = new ArrayList<Integer>();
		System.out.println(Runtime.getRuntime().freeMemory());
		while (loop){
			try{
				lista.add(new Integer(33));
			}catch(OutOfMemoryError err){
				System.out.println(Runtime.getRuntime().freeMemory());
			}
		}		
	}
}

Realmente, o exemplo do renamed é melhor, pois a memória acaba. No meu exemplo a pilha estoura.

[]'s

É bom lembrar que a VM tem uma quantidade de memória máxima que ela aloca, e ela é bem diferente do máximo possível do SO. Por padrão, a VM aloca no máximo 64mb de RAM. Você pode alterar a configuração com o parâmetro -XMX, na hora de executar seu aplicativo.

Veja:
http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp

Mesmo o SO também estipula limites máximos para o tamanho dos processos, no caso do Windows, 4GB para 32 bits, e 8 TB para as versões de 64:
http://msdn.microsoft.com/en-us/library/aa366778(VS.85).aspx

Como vc pode ver, mesmo um aplicativo nativo muito determinado, não conseguirá acabar com toda RAM e toda memória virtual do HD de alguém, a menos que esteja abaixo desses limites. E por isso também que, se você quer acabar mesmo com a memória de alguém, você deve fazer um processo que dispare subprocessos. Como o clássico programa em C:

while (true) { fork(); }

[quote=davidbuzatto]Realmente, o exemplo do renamed é melhor, pois a memória acaba. No meu exemplo a pilha estoura.

[]'s[/quote]

Por que na recursão estoura a pilha e no outro exemplo acaba a memória?

[quote=diogojava123][quote=davidbuzatto]Realmente, o exemplo do renamed é melhor, pois a memória acaba. No meu exemplo a pilha estoura.

[]'s[/quote]

Por que na recursão estoura a pilha e no outro exemplo acaba a memória?[/quote]

Isso tem haver como o seu sistema operacional gerencia a memória. Da uma lida aqui.

Por que o limite máximo da pilha é atingido antes do limite máximo da memória. O java usa para o stack (aprox. 512KB) uma quantia bem menor do que para o heap (64MB).

Veja mais informações em:
http://www.odi.ch/weblog/posting.php?posting=411

Pessoal obrigado pelas respostas na verdade isso foi mais por curiosidade para saber o que acontece quando fica sobrecarregado mas cada computador e sistema operacional têm suas limitações. Talvez vocês possam me passar uma idéia básica para me ajudar em um programa que estou tentando fazer: http://www.guj.com.br/java/230913-enviar-arquivos-a-diretorios-e-remove-los#1186404