A classe Runtime é utilizada para se comunicar com o ambiente que a JVM está executando. Por exemplo: utilizamos ela para carregar DLLs (Windows) ou SOs (Linux), através do método load. Cada aplicação Java possui uma única instância e podemos obter essa instância através do método estático getRuntime(). A seguir temos um exemplo de alguns métodos bem bacanas dessa classe:
package br.com.thiagovespa.system.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class SystemInfo {
public static String execute(String command) {
String s;
StringBuilder result = new StringBuilder();
BufferedReader stdInput = null;
try {
Process p = Runtime.getRuntime().exec(command);
stdInput = new BufferedReader(new InputStreamReader(
p.getInputStream()));
while ((s = stdInput.readLine()) != null) {
result.append(s).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (stdInput != null) {
try {
stdInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result.toString();
}
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
System.out.println("Número de processadores disponíveis: "
+ rt.availableProcessors() + " \n");
System.out.println(execute("free"));
System.out.println("Memória disponível na JVM antes do GC: "
+ rt.freeMemory() + " bytes de " + rt.totalMemory()
+ " bytes - Máximo: " + rt.maxMemory() + " bytes");
rt.gc();
System.out.println("Memória disponível na JVM após o GC: "
+ rt.freeMemory() + " bytes de " + rt.totalMemory()
+ " bytes - Máximo: " + rt.maxMemory() + " bytes");
rt.exit(0);
}
}
Na linha 15 executamos um comando ou aplicativo externo. Para isso criei um método a parte. O exec possui várias sobrecargas podendo ser executado passando parâmetros, com variáveis de ambiente, entre outros. Nesse exemplo, ele executa o comando free do linux, e armazeno em uma String para exibir a quantidade de memória livre do sistema operacional. Esse mesmo código pode ser utilizado para executar qualquer comando ou aplicativo externo à uma aplicação Java. Existe a possibilidade de recuperar o stream de entrada, de saída e de erro para poder manipular o comando/aplicativo.
Na linha 41, tem um método interessante, que recupera a quantidade de processadores disponível para a máquina virtual. Esse recurso pode ser útil no desenvolvimento de programas que executem código paralelo. Nas linhas 46 e 47, consigo monitorar a quantidade de memória livre, total e máxima alocada no momento para a aplicação Java.
A linha 48 é responsável por solicitar à JVM a execução do Garbage Collector para liberação de memória não referenciada. Pela especificação essa execução não é garantida, ao chamar esse método ele apenas sugere a execução. Uma outra forma de se chamar é pela classe System (System.gc()). Na linha 52 eu finalizo o programa com o código 0 (sem erro). Essa chamada não é necessária, mas ilustra um dos métodos da classe Runtime.
A saída desse programa é a seguinte:
Número de processadores disponíveis: 4
total used free shared buffers cached
Mem: 8193120 6553088 1640032 0 554160 2031860
-/+ buffers/cache: 3967068 4226052
Swap: 8193144 0 8193144
Memória disponível na JVM antes do GC: 124384688 bytes de 125698048 bytes - Máximo: 1866006528 bytes
Memória disponível na JVM após o GC: 124902352 bytes de 125698048 bytes - Máximo: 1866006528 bytes
Dessa maneira você pode ter um controle maior sobre sua aplicação e executar programas externos.
Excelente post, Thiago!
Na linha 49 da classe de exemplo, você se esqueceu de alterar o texto do comando System.out.println() após a chamada para o GC.
Muito obrigado! Já corrigido!
Muito bom, me ajudou!!! Obrigado!!!!