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!!!!