Olá Gujer’s, venho aqui hoje tirar uma dúvida.
Estou desenvolvendo um sistema que “filma” o que o usuario esta fazendo em seu computador, ou seja ele vai tirando print screen das telas para no final transformar isso em um vídeo que pode ser comentado pelo usuário usando um microfone, mas até aqui tudo bem, a minha dúvida é a seguinte, qual a melhor forma de se trabalhar com Threads, eu ja usei as Threads normais e também as pools Threads, atualmente to usando pool Thread mas não sei se é a melhor opção pq as pool Thread não “morrem” assim que o método run é terminado ao meu ponto de vista isso não é bom pq a memoria fica alocada para essas threads, eu fiz um teste acompanho a quantidade de memoria disponivel usando o gerenciador de tarefas do windows, ao iniciar o programa ele alocava mais ou menos uns 300 MB para as threads e quando eu clico em parar o que significa que o metodo run chega ao seu fim mas parece que a Thread ainda continua ativa pq os 300MB usado por ela são foi desalocado.
O problema é que se eu clico em gravar novamente além desses 300 MB alocados na primeira vez que começou a ser gravado é alocado mais uns 300 MB ou seja agora são 600MB em Threads, existe alguma alternativa para desalocar da memoria as threads que não estão sendo utilizadas?
Tb tem o problema do uso do CPU, qdo as Thread estão sendo executado o uso da CPU vai a 100%.
A menos que você tenha uma quantidade absurda de threads, isso não deveria ser problema.
Se você tem um memory leak, é porque algum objeto ficou referenciado. Geralmente variáveis estáticas causam leaks desse tipo.
Use o profiler do Netbeans para identificar que objetos estão alocados e quem os está mantendo vivos.
Eu crio somente 2 Threads uma Thread que captura as telas e adiciona em um ArrayList as imagens que serão gravadas em disco, e outra Thread que le esse vetor e vai gravando as imagens em disco e removendo do vetor.
Então problema de muita Thread não é.
Mas realmente pode ser algumas variaveis que estejam sendo referenciadas, pq no metodo run eu uso variaveis de instancia. vou usar o profiler do netbeans como vc sugeriu para ver se é isso mesmo
Bom fiz o teste aqui, e eu tinha me esquecido de citar uma outra Thread o que na verdade é que no total são 3 Threads é a primeira Thread que não está morrendo é uma SwingWorker.
Fiz uma alteração e executei essa SwingWorker com pool e quando eu clico em parar eu mato essa SwingWorker com o método shutdownNow(), bom isso já resolveu esse problema.
Brigadão Vinny.
Mas ainda tem o problema de processamento, dei uma lida e pode ser pq o método de capturar e de gravar as imagens estão dentro de um while infinito sem Thread.Sleep, o problema é que eu não posso colocar um sleep na thread de captura senão o video vai dar a impressão que ta legado, travando, e nem no metodo de gravar a imagem em disco pq senao vai começar a enxer muito o vetor e vai resultar em um OutMemoryError por falta de mémoria, tem alguma coisa além do sleep que eu possa estar fazendo para diminuir o uso da CPU pela thread?
Você pode fazer um Thread.sleep(1).
Ou então, use um controle de loop mais sofisticado, como os jogos fazem:
http://www.pontov.com.br/site/index.php/java/48-java2d/121-o-loop-de-animacao
Não imaginava que um sleep(1) ia fazer diferença, mas fez o uso da CPU realmente diminuiu, também usei o controle de loop para jogos para melhorar o desempenho da thread de captura de tela, fico muito bom.
Obrigado mais uma vez.
Abraço
Faz pq o Sleep(1) dá uma mensagem para o SO: Essa é uma boa hora para fazer preempção. Assim o SO sabe que poderá repassar a atividade para outros processos e o consumo da aplicação cai.
Mas o ideal é usar um loop de animação mais aprimorado, pois aí vc pode dar metas das taxas de update por segundo e tentar garantir taxas de atualização constantes na sua aplicação. Isso melhora muito a qualidade do vídeo e, em máquinas muito rápidas, libera bastante processador.
Um outro ponto que acho legal mencionar: muitas vezes podemos reduzir o stack size (com o parâmetro -Xss) e evitar que as Threads consumam mais memória.
Em sistemas de 64 bits o stack size geralmente é 1 MB, o que para muitos sistemas é um desperdício de memória. O valor para sistemas de 32 bits eu não me recordo.
Claro que isso faz muita diferença quando temos muitas threads rodando (como no caso de um servidor de aplicação, por exemplo). Não creio que possa ser o seu caso, mas fica a dica 