{"id":414,"date":"2021-12-22T18:44:41","date_gmt":"2021-12-22T18:44:41","guid":{"rendered":"https:\/\/sidroniolima.com.br\/blog\/?p=414"},"modified":"2021-12-23T16:04:30","modified_gmt":"2021-12-23T16:04:30","slug":"garbage-collector-gc","status":"publish","type":"post","link":"https:\/\/sidroniolima.com.br\/blog\/2021\/12\/22\/garbage-collector-gc\/","title":{"rendered":"Garbage Collector (GC)"},"content":{"rendered":"\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?text=Como%20o%20GC%20funciona%2C%20quem%20chama%2C%20porqu%C3%AA%20n%C3%A3o%20deveria%20ser%20manualmente%20invocado%20e%20cuidado%20ao%20invocar%20o%20finalize%28%29.&#038;hashtags=garbagecollector%2Cgc%2Cjava%2Cperformance&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n\n<p>Java \u00e9 considerada uma <strong><em>managed languaged <\/em><\/strong>e, portanto, os objetos que s\u00e3o criados e armazenados no <strong><em>Heap <\/em><\/strong>s\u00e3o automaticamente liberados da mem\u00f3ria quando um processo especial os elege para tal.<\/p>\n<p>Esse processo \u00e9 conhecido como <strong><em>Garbage Collector<\/em><\/strong> (coletor de lixo) e<\/p>\n<blockquote>\n<p>&#8230;foi inventado<span data-offset-key=\"a4k3q-0-0\"> por John McCarthy por volta de 1959 para resolver problemas de gerenciamento manual de mem\u00f3ria em Lisp. <\/span><\/p>\n<\/blockquote>\n<p>Linguagens como <strong>C<\/strong> e <strong>C++<\/strong> n\u00e3o possuem este mecanismo e a responsabilidade pela libera\u00e7\u00e3o de mem\u00f3ria fica com o programador, que deve invocar o m\u00e9todo <em>free<\/em> para os objetos que n\u00e3o ser\u00e3o mais utilizados. Algo parecido ocorre em <strong>Visual Basic<\/strong>, mas nela o programador deve apontar o objeto para <em>null.<\/em><\/p>\n<p>O mecanismo do <strong>GC<\/strong> em Java \u00e9 simples: se um objeto n\u00e3o puder ser alcan\u00e7ado por uma refer\u00eancia a ele na <em><strong>Stack<\/strong>,<\/em> ent\u00e3o ele ser\u00e1 marcado como eleg\u00edvel para coleta. Objetos est\u00e1ticos, cujas refer\u00eancias ficam no <strong><em>Metaspace<\/em><\/strong>, nunca ser\u00e3o eleitos pois nunca perdem a refer\u00eancia.<\/p>\n<p>Embora seja autom\u00e1tico e executado em uma <strong><em>Thread<\/em><\/strong> independente, \u00e9 poss\u00edvel invocar o processo por meio do m\u00e9todo <em>System.gc()<\/em>. Entretanto essa chamada apenas sugere que o <strong><em>GC<\/em><\/strong> seja executado. Sua execu\u00e7\u00e3o fica a cargo da <em>JVM, <\/em>que decidi faz\u00ea-lo ou esperar por outro momento mais oportuno.<\/p>\n<p>Na vers\u00e3o 1.8 e anteriores, a <em>JVM<\/em> alocava a quantidade de mem\u00f3ria definida na vari\u00e1vel <code>-Xms<\/code> e mesmo ap\u00f3s a execu\u00e7\u00e3o o <em>GC<\/em> essa mem\u00f3ria permanecia alocada. A partir do <em>Java<\/em> 11, \u00e9 poss\u00edvel que a mem\u00f3ria seja liberada e devolvida ao sistema operacional. Por quest\u00f5es de performance pode ser que isso n\u00e3o ocorra.<\/p>\n<p>Essa diferen\u00e7a de comportamento nas vers\u00f5es \u00e9 interessant\u00edssima. Abaixo segue um gr\u00e1fico mensal de uso de mem\u00f3ria de uma aplica\u00e7\u00e3o <strong><em>Web<\/em><\/strong> na vers\u00e3o 1.8 do <strong><em>Java<\/em><\/strong>.<\/p>\n<div id=\"attachment_416\" style=\"width: 1354px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-416\" class=\"size-full wp-image-416\" src=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage.png\" alt=\"Gr\u00e1fico de uso de mem\u00f3ria\" width=\"1344\" height=\"533\" srcset=\"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage.png 1344w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage-300x119.png 300w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage-1024x406.png 1024w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage-768x305.png 768w, https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/java-memory-usage-620x246.png 620w\" sizes=\"auto, (max-width: 1344px) 100vw, 1344px\" \/><\/a><p id=\"caption-attachment-416\" class=\"wp-caption-text\">Como pode-se observar, a quantidade de mem\u00f3ria apenas diminui para o patamar inicial em momentos de rein\u00edcio do servidor, ocorrido entre 01\/12 e 03\/12. Quem n\u00e3o conhece o mecanismo, pode achar que ele n\u00e3o est\u00e1 sendo executado ou ocorrendo alguma falha.<\/p><\/div>\n<p>A chamada manual do m\u00e9todo <em>System.gc() <\/em>pode resultar em perda de performance, uma vez que ele utiliza recursos da <strong>JVM<\/strong> que estariam alocados na aplica\u00e7\u00e3o. Portanto \u00e9 sugerido que a execu\u00e7\u00e3o do <em>GC<\/em> seja feita de forma autom\u00e1tica e controlada pela <strong>JVM<\/strong>.<\/p>\n<p>Mas o que ocorre ap\u00f3s os objetos estarem eleg\u00edveis para serem coletados pelo <em>GC<\/em>? At\u00e9 a vers\u00e3o 1.9 do <strong>Java<\/strong>, o m\u00e9todo <em>Object.finalize<\/em> era chamado antes dos objetos serem removidos fisicamente do <strong><em>Heap<\/em><\/strong>. Nas vers\u00f5es superiores ele foi marcado como <em>@deprecated<\/em>. H\u00e1 um problema em rela\u00e7\u00e3o a este m\u00e9todo: <strong>n\u00e3o h\u00e1 garantia do momento de sua execu\u00e7\u00e3o<\/strong>. Imagine que ele seja chamado para liberar algum recurso mas a aplica\u00e7\u00e3o terminar antes. O recurso ficar\u00e1 em execu\u00e7\u00e3o ou aberto.<\/p>\n<p>Esse post foi uma explica\u00e7\u00e3o do que o GC \u00e9, como funciona, quando e por quem \u00e9 chamado. Al\u00e9m de apresentada uma armadilha na sua execu\u00e7\u00e3o.<\/p>\n<p>Em outros, retomarei a falar de mem\u00f3ria e performance.<\/p>\n<p>At\u00e9.<\/p>\n<p>Fontes:<\/p>\n<p><a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Runtime.html#gc()\">https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Runtime.html#gc()<\/a><\/p>\n<p><a href=\"https:\/\/www.udemy.com\/course\/java-application-performance-and-memory-management\">https:\/\/www.udemy.com\/course\/java-application-performance-and-memory-management<\/a><\/p>\n<p><a href=\"https:\/\/pt.wikipedia.org\/wiki\/Coletor_de_lixo_(inform%C3%A1tica)\">https:\/\/pt.wikipedia.org\/wiki\/Coletor_de_lixo_(inform%C3%A1tica)<\/a><\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?text=Como%20o%20GC%20funciona%2C%20quem%20chama%2C%20porqu%C3%AA%20n%C3%A3o%20deveria%20ser%20manualmente%20invocado%20e%20cuidado%20ao%20invocar%20o%20finalize%28%29.&#038;hashtags=garbagecollector%2Cgc%2Cjava%2Cperformance&#038;via=sidroniolima\" class=\"twitter-share-button\">Tweet<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Java \u00e9 considerada uma managed languaged e, portanto, os objetos que s\u00e3o criados e armazenados no Heap s\u00e3o automaticamente liberados da mem\u00f3ria quando um processo especial os elege para tal. Esse processo \u00e9 conhecido como Garbage Collector (coletor de lixo) e &#8230;foi inventado por John McCarthy por volta de 1959 para resolver problemas de gerenciamento [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":419,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[27,116],"tags":[118,29,117,119],"class_list":["post-414","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","category-performance","tag-garbage-collector","tag-java","tag-performance","tag-trap"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/sidroniolima.com.br\/blog\/wp-content\/uploads\/2021\/12\/trash.jpg","_links":{"self":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/414","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/comments?post=414"}],"version-history":[{"count":6,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/414\/revisions"}],"predecessor-version":[{"id":422,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/posts\/414\/revisions\/422"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/media\/419"}],"wp:attachment":[{"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/media?parent=414"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/categories?post=414"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sidroniolima.com.br\/blog\/wp-json\/wp\/v2\/tags?post=414"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}