Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas

Detalhes bibliográficos
Autor(a) principal: VARJÃO, Filipe Rafael Gomes
Data de Publicação: 2019
Tipo de documento: Dissertação
Idioma: por
Título da fonte: Repositório Institucional da UFPE
dARK ID: ark:/64986/0013000006qv1
Texto Completo: https://repositorio.ufpe.br/handle/123456789/34460
Resumo: Desde o algoritmo de Mark-Scan desenvolvido para a linguagem LISP por John Mc- Marthy em 1960, diversas técnicas foram desenvolvidas para gerenciar dinamicamente a memória de forma automática. Tais técnicas buscam coletar todos os dados, mantendo as pausas do programa de usuário mínimo. A contagem de referência é um método simples, no qual o gerenciamento de memória é realizado em pequenas etapas intercaladas com computação. Esse método evita grandes pausas de programa introduzidas por outras técnicas, como a marcação e varredura e a coleta por cópia. No entanto, a versão original da contagem de referência é incapaz de recuperar estruturas cíclicas. A solução geral para tal problema foi a introdução da varredura local. Combinando a contagem de referência com detecção cíclica e o gerenciamento de memória baseado em região, é possível diminuir o número de verificações e atualizações nas contagens das células em heap, reduzindo a duração das pausas e o espaço em memória. O gerenciamento de memória baseado em região faz uso de análise estática e instrumentação de código. O compilador tenta identificar a vida útil dos objetos, agrupando aqueles de longevidade semelhante em uma mesma região (geralmente contígua) de memória a ser recuperada quando não forem mais necessárias. Esta tese propõe um novo algoritmo de gerenciamento de memória baseado na contagem de referências cíclicas, combinado com o gerenciamento de memória baseado em região, fazendo uso de técnicas estáticas e de tempo de execução, trabalhando em conjunto para reduzir os gargalos um do outro. A mesclagem de contagem de referência e gerenciamento de memória baseado em região foi usada para coletar os dados alocados em grupos. As duas técnicas são usadas para reciclar as diferentes partes da memória, aumentando a velocidade de recuperação de objetos e reduzindo o uso da memória. Com o compilador implementado em Go, são inseridas barreiras de gravação após cada operação de armazenamento de um ponteiro na memória, atualizando as contagens de referência de todas as células envolvidas. O alocador de células segrega os objetos por seu tamanho, gerenciando listas que contêm os blocos livres de um tamanho específico com a contagem de referência armazenada em cada objeto. Essa modificação limita a varredura de marca local apenas a ciclos de pesquisa preguiçosos, evitando varrer todo o heap. Em comparação com o algoritmo de contagem de referências e detecção de ciclos, observam-se ganhos de desempenho em até 30% em tempo de execução e 50% a menos de uso de memória para programas que exigem grandes quantidades de memória e não fazem pausas no processo do usuário, esses valores podem apresentar maiores ganhos quando são combinadas as técnicas de contagem de referências e o gerenciamento de memória baseado em regiões.
id UFPE_6cc6a92ccf9fb22b66262bdfb63abe37
oai_identifier_str oai:repositorio.ufpe.br:123456789/34460
network_acronym_str UFPE
network_name_str Repositório Institucional da UFPE
repository_id_str 2221
spelling VARJÃO, Filipe Rafael Gomeshttp://lattes.cnpq.br/5460816819533256http://lattes.cnpq.br/7601016626256808LINS, Rafael Dueire2019-10-10T20:52:15Z2019-10-10T20:52:15Z2019-03-14https://repositorio.ufpe.br/handle/123456789/34460ark:/64986/0013000006qv1Desde o algoritmo de Mark-Scan desenvolvido para a linguagem LISP por John Mc- Marthy em 1960, diversas técnicas foram desenvolvidas para gerenciar dinamicamente a memória de forma automática. Tais técnicas buscam coletar todos os dados, mantendo as pausas do programa de usuário mínimo. A contagem de referência é um método simples, no qual o gerenciamento de memória é realizado em pequenas etapas intercaladas com computação. Esse método evita grandes pausas de programa introduzidas por outras técnicas, como a marcação e varredura e a coleta por cópia. No entanto, a versão original da contagem de referência é incapaz de recuperar estruturas cíclicas. A solução geral para tal problema foi a introdução da varredura local. Combinando a contagem de referência com detecção cíclica e o gerenciamento de memória baseado em região, é possível diminuir o número de verificações e atualizações nas contagens das células em heap, reduzindo a duração das pausas e o espaço em memória. O gerenciamento de memória baseado em região faz uso de análise estática e instrumentação de código. O compilador tenta identificar a vida útil dos objetos, agrupando aqueles de longevidade semelhante em uma mesma região (geralmente contígua) de memória a ser recuperada quando não forem mais necessárias. Esta tese propõe um novo algoritmo de gerenciamento de memória baseado na contagem de referências cíclicas, combinado com o gerenciamento de memória baseado em região, fazendo uso de técnicas estáticas e de tempo de execução, trabalhando em conjunto para reduzir os gargalos um do outro. A mesclagem de contagem de referência e gerenciamento de memória baseado em região foi usada para coletar os dados alocados em grupos. As duas técnicas são usadas para reciclar as diferentes partes da memória, aumentando a velocidade de recuperação de objetos e reduzindo o uso da memória. Com o compilador implementado em Go, são inseridas barreiras de gravação após cada operação de armazenamento de um ponteiro na memória, atualizando as contagens de referência de todas as células envolvidas. O alocador de células segrega os objetos por seu tamanho, gerenciando listas que contêm os blocos livres de um tamanho específico com a contagem de referência armazenada em cada objeto. Essa modificação limita a varredura de marca local apenas a ciclos de pesquisa preguiçosos, evitando varrer todo o heap. Em comparação com o algoritmo de contagem de referências e detecção de ciclos, observam-se ganhos de desempenho em até 30% em tempo de execução e 50% a menos de uso de memória para programas que exigem grandes quantidades de memória e não fazem pausas no processo do usuário, esses valores podem apresentar maiores ganhos quando são combinadas as técnicas de contagem de referências e o gerenciamento de memória baseado em regiões.From the Mark-Scan algorithm developed for the LISP language by John McMarthy in 1960, many techniques have been developed to proper and automatically manage memory. Such techniques seek to collect all possible unreachable data, keeping program pauses to a minimum. Reference counting is a simple method, in which memory management is performed in small steps interleaved with computation, it avoids the large program pauses introduced by other techniques such as mark-sweep and copying. However, the originalversion of reference counting is unable to reclaim cyclic structures. The general solution for such a problem was introducing local mark-sweep. Combining the reference counting with cyclic detection and the region-based memory management, which decreases the number of checks and updates to the counts of the cells in heap, reducing the length of pauses and memory footprint. Region-based memory management makes use of static analysis and runtime instrumentation. The compiler tries to identify the lifetime of objects, clustering the ones with similar life span in the same region (often contiguous) of memory to be reclaimed when they are no longer needed. The merge of reference counting and region-based memory management was used in to collect the data allocated in groups. Here, both techniques are used to recycle the different parts of the memory, increasing the speed of object reclamation while also decreasing the overall footprint of the program. Region-based memory management, a compile-time technique, and reference counting, a run-time algorithm, work together to eliminate some of the disadvantages of each other. In the implementation reported here, the Go compiler inserts a write barrier after every store operation of a pointer into memory, updating the reference counts of all the cells involved. The cell allocator also segregates the objects by their size, managing lists which hold the free blocks of a particular size with the reference count stored in each object. This modification limits the local mark-sweep to lazily search cycles only, avoiding to scan the entire heap. This thesis reports on a new memory management algorithm based on cyclic reference counting combined with region-based memory management, which makes use of static and runtime techniques, working together to reduce the bottlenecks of one another. The presented scheme yields performance gains for programs that claim for large quantities of memory as 30% off to runtime and 50% less of memory usage, those values can grow when is combined reference counting and region-based memory management, it makes no pauses of the user process, an essential feature for real-time systems.porUniversidade Federal de PernambucoPrograma de Pos Graduacao em Ciencia da ComputacaoUFPEBrasilAttribution-NonCommercial-NoDerivs 3.0 Brazilhttp://creativecommons.org/licenses/by-nc-nd/3.0/br/info:eu-repo/semantics/openAccessEngenharia de softwareGerenciamento de memóriaGerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicasinfo:eu-repo/semantics/publishedVersioninfo:eu-repo/semantics/masterThesisdoutoradoreponame:Repositório Institucional da UFPEinstname:Universidade Federal de Pernambuco (UFPE)instacron:UFPETHUMBNAILTESE Filipe Rafael Gomes Varjão.pdf.jpgTESE Filipe Rafael Gomes Varjão.pdf.jpgGenerated Thumbnailimage/jpeg1246https://repositorio.ufpe.br/bitstream/123456789/34460/5/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf.jpg9ab5c4ae5c67a30abb9c05ce4385d458MD55ORIGINALTESE Filipe Rafael Gomes Varjão.pdfTESE Filipe Rafael Gomes Varjão.pdfapplication/pdf1526612https://repositorio.ufpe.br/bitstream/123456789/34460/1/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf85986fe5d5feac320b570758051d5219MD51CC-LICENSElicense_rdflicense_rdfapplication/rdf+xml; charset=utf-8811https://repositorio.ufpe.br/bitstream/123456789/34460/2/license_rdfe39d27027a6cc9cb039ad269a5db8e34MD52LICENSElicense.txtlicense.txttext/plain; charset=utf-82310https://repositorio.ufpe.br/bitstream/123456789/34460/3/license.txtbd573a5ca8288eb7272482765f819534MD53TEXTTESE Filipe Rafael Gomes Varjão.pdf.txtTESE Filipe Rafael Gomes Varjão.pdf.txtExtracted texttext/plain189917https://repositorio.ufpe.br/bitstream/123456789/34460/4/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf.txtbd67fd6ea77ba55f087407be7db14f6eMD54123456789/344602019-10-26 03:55:43.996oai:repositorio.ufpe.br:123456789/34460TGljZW7Dp2EgZGUgRGlzdHJpYnVpw6fDo28gTsOjbyBFeGNsdXNpdmEKClRvZG8gZGVwb3NpdGFudGUgZGUgbWF0ZXJpYWwgbm8gUmVwb3NpdMOzcmlvIEluc3RpdHVjaW9uYWwgKFJJKSBkZXZlIGNvbmNlZGVyLCDDoCBVbml2ZXJzaWRhZGUgRmVkZXJhbCBkZSBQZXJuYW1idWNvIChVRlBFKSwgdW1hIExpY2Vuw6dhIGRlIERpc3RyaWJ1acOnw6NvIE7Do28gRXhjbHVzaXZhIHBhcmEgbWFudGVyIGUgdG9ybmFyIGFjZXNzw612ZWlzIG9zIHNldXMgZG9jdW1lbnRvcywgZW0gZm9ybWF0byBkaWdpdGFsLCBuZXN0ZSByZXBvc2l0w7NyaW8uCgpDb20gYSBjb25jZXNzw6NvIGRlc3RhIGxpY2Vuw6dhIG7Do28gZXhjbHVzaXZhLCBvIGRlcG9zaXRhbnRlIG1hbnTDqW0gdG9kb3Mgb3MgZGlyZWl0b3MgZGUgYXV0b3IuCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwoKTGljZW7Dp2EgZGUgRGlzdHJpYnVpw6fDo28gTsOjbyBFeGNsdXNpdmEKCkFvIGNvbmNvcmRhciBjb20gZXN0YSBsaWNlbsOnYSBlIGFjZWl0w6EtbGEsIHZvY8OqIChhdXRvciBvdSBkZXRlbnRvciBkb3MgZGlyZWl0b3MgYXV0b3JhaXMpOgoKYSkgRGVjbGFyYSBxdWUgY29uaGVjZSBhIHBvbMOtdGljYSBkZSBjb3B5cmlnaHQgZGEgZWRpdG9yYSBkbyBzZXUgZG9jdW1lbnRvOwpiKSBEZWNsYXJhIHF1ZSBjb25oZWNlIGUgYWNlaXRhIGFzIERpcmV0cml6ZXMgcGFyYSBvIFJlcG9zaXTDs3JpbyBJbnN0aXR1Y2lvbmFsIGRhIFVGUEU7CmMpIENvbmNlZGUgw6AgVUZQRSBvIGRpcmVpdG8gbsOjbyBleGNsdXNpdm8gZGUgYXJxdWl2YXIsIHJlcHJvZHV6aXIsIGNvbnZlcnRlciAoY29tbyBkZWZpbmlkbyBhIHNlZ3VpciksIGNvbXVuaWNhciBlL291IGRpc3RyaWJ1aXIsIG5vIFJJLCBvIGRvY3VtZW50byBlbnRyZWd1ZSAoaW5jbHVpbmRvIG8gcmVzdW1vL2Fic3RyYWN0KSBlbSBmb3JtYXRvIGRpZ2l0YWwgb3UgcG9yIG91dHJvIG1laW87CmQpIERlY2xhcmEgcXVlIGF1dG9yaXphIGEgVUZQRSBhIGFycXVpdmFyIG1haXMgZGUgdW1hIGPDs3BpYSBkZXN0ZSBkb2N1bWVudG8gZSBjb252ZXJ0w6otbG8sIHNlbSBhbHRlcmFyIG8gc2V1IGNvbnRlw7pkbywgcGFyYSBxdWFscXVlciBmb3JtYXRvIGRlIGZpY2hlaXJvLCBtZWlvIG91IHN1cG9ydGUsIHBhcmEgZWZlaXRvcyBkZSBzZWd1cmFuw6dhLCBwcmVzZXJ2YcOnw6NvIChiYWNrdXApIGUgYWNlc3NvOwplKSBEZWNsYXJhIHF1ZSBvIGRvY3VtZW50byBzdWJtZXRpZG8gw6kgbyBzZXUgdHJhYmFsaG8gb3JpZ2luYWwgZSBxdWUgZGV0w6ltIG8gZGlyZWl0byBkZSBjb25jZWRlciBhIHRlcmNlaXJvcyBvcyBkaXJlaXRvcyBjb250aWRvcyBuZXN0YSBsaWNlbsOnYS4gRGVjbGFyYSB0YW1iw6ltIHF1ZSBhIGVudHJlZ2EgZG8gZG9jdW1lbnRvIG7Do28gaW5mcmluZ2Ugb3MgZGlyZWl0b3MgZGUgb3V0cmEgcGVzc29hIG91IGVudGlkYWRlOwpmKSBEZWNsYXJhIHF1ZSwgbm8gY2FzbyBkbyBkb2N1bWVudG8gc3VibWV0aWRvIGNvbnRlciBtYXRlcmlhbCBkbyBxdWFsIG7Do28gZGV0w6ltIG9zIGRpcmVpdG9zIGRlCmF1dG9yLCBvYnRldmUgYSBhdXRvcml6YcOnw6NvIGlycmVzdHJpdGEgZG8gcmVzcGVjdGl2byBkZXRlbnRvciBkZXNzZXMgZGlyZWl0b3MgcGFyYSBjZWRlciDDoApVRlBFIG9zIGRpcmVpdG9zIHJlcXVlcmlkb3MgcG9yIGVzdGEgTGljZW7Dp2EgZSBhdXRvcml6YXIgYSB1bml2ZXJzaWRhZGUgYSB1dGlsaXrDoS1sb3MgbGVnYWxtZW50ZS4gRGVjbGFyYSB0YW1iw6ltIHF1ZSBlc3NlIG1hdGVyaWFsIGN1am9zIGRpcmVpdG9zIHPDo28gZGUgdGVyY2Vpcm9zIGVzdMOhIGNsYXJhbWVudGUgaWRlbnRpZmljYWRvIGUgcmVjb25oZWNpZG8gbm8gdGV4dG8gb3UgY29udGXDumRvIGRvIGRvY3VtZW50byBlbnRyZWd1ZTsKZykgU2UgbyBkb2N1bWVudG8gZW50cmVndWUgw6kgYmFzZWFkbyBlbSB0cmFiYWxobyBmaW5hbmNpYWRvIG91IGFwb2lhZG8gcG9yIG91dHJhIGluc3RpdHVpw6fDo28gcXVlIG7Do28gYSBVRlBFLCBkZWNsYXJhIHF1ZSBjdW1wcml1IHF1YWlzcXVlciBvYnJpZ2HDp8O1ZXMgZXhpZ2lkYXMgcGVsbyByZXNwZWN0aXZvIGNvbnRyYXRvIG91IGFjb3Jkby4KCkEgVUZQRSBpZGVudGlmaWNhcsOhIGNsYXJhbWVudGUgbyhzKSBub21lKHMpIGRvKHMpIGF1dG9yIChlcykgZG9zIGRpcmVpdG9zIGRvIGRvY3VtZW50byBlbnRyZWd1ZSBlIG7Do28gZmFyw6EgcXVhbHF1ZXIgYWx0ZXJhw6fDo28sIHBhcmEgYWzDqW0gZG8gcHJldmlzdG8gbmEgYWzDrW5lYSBjKS4KRepositório InstitucionalPUBhttps://repositorio.ufpe.br/oai/requestattena@ufpe.bropendoar:22212019-10-26T06:55:43Repositório Institucional da UFPE - Universidade Federal de Pernambuco (UFPE)false
dc.title.pt_BR.fl_str_mv Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
title Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
spellingShingle Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
VARJÃO, Filipe Rafael Gomes
Engenharia de software
Gerenciamento de memória
title_short Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
title_full Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
title_fullStr Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
title_full_unstemmed Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
title_sort Gerenciamento dinâmico de memória baseado em regiões com contagem de referências cíclicas
author VARJÃO, Filipe Rafael Gomes
author_facet VARJÃO, Filipe Rafael Gomes
author_role author
dc.contributor.authorLattes.pt_BR.fl_str_mv http://lattes.cnpq.br/5460816819533256
dc.contributor.advisorLattes.pt_BR.fl_str_mv http://lattes.cnpq.br/7601016626256808
dc.contributor.author.fl_str_mv VARJÃO, Filipe Rafael Gomes
dc.contributor.advisor1.fl_str_mv LINS, Rafael Dueire
contributor_str_mv LINS, Rafael Dueire
dc.subject.por.fl_str_mv Engenharia de software
Gerenciamento de memória
topic Engenharia de software
Gerenciamento de memória
description Desde o algoritmo de Mark-Scan desenvolvido para a linguagem LISP por John Mc- Marthy em 1960, diversas técnicas foram desenvolvidas para gerenciar dinamicamente a memória de forma automática. Tais técnicas buscam coletar todos os dados, mantendo as pausas do programa de usuário mínimo. A contagem de referência é um método simples, no qual o gerenciamento de memória é realizado em pequenas etapas intercaladas com computação. Esse método evita grandes pausas de programa introduzidas por outras técnicas, como a marcação e varredura e a coleta por cópia. No entanto, a versão original da contagem de referência é incapaz de recuperar estruturas cíclicas. A solução geral para tal problema foi a introdução da varredura local. Combinando a contagem de referência com detecção cíclica e o gerenciamento de memória baseado em região, é possível diminuir o número de verificações e atualizações nas contagens das células em heap, reduzindo a duração das pausas e o espaço em memória. O gerenciamento de memória baseado em região faz uso de análise estática e instrumentação de código. O compilador tenta identificar a vida útil dos objetos, agrupando aqueles de longevidade semelhante em uma mesma região (geralmente contígua) de memória a ser recuperada quando não forem mais necessárias. Esta tese propõe um novo algoritmo de gerenciamento de memória baseado na contagem de referências cíclicas, combinado com o gerenciamento de memória baseado em região, fazendo uso de técnicas estáticas e de tempo de execução, trabalhando em conjunto para reduzir os gargalos um do outro. A mesclagem de contagem de referência e gerenciamento de memória baseado em região foi usada para coletar os dados alocados em grupos. As duas técnicas são usadas para reciclar as diferentes partes da memória, aumentando a velocidade de recuperação de objetos e reduzindo o uso da memória. Com o compilador implementado em Go, são inseridas barreiras de gravação após cada operação de armazenamento de um ponteiro na memória, atualizando as contagens de referência de todas as células envolvidas. O alocador de células segrega os objetos por seu tamanho, gerenciando listas que contêm os blocos livres de um tamanho específico com a contagem de referência armazenada em cada objeto. Essa modificação limita a varredura de marca local apenas a ciclos de pesquisa preguiçosos, evitando varrer todo o heap. Em comparação com o algoritmo de contagem de referências e detecção de ciclos, observam-se ganhos de desempenho em até 30% em tempo de execução e 50% a menos de uso de memória para programas que exigem grandes quantidades de memória e não fazem pausas no processo do usuário, esses valores podem apresentar maiores ganhos quando são combinadas as técnicas de contagem de referências e o gerenciamento de memória baseado em regiões.
publishDate 2019
dc.date.accessioned.fl_str_mv 2019-10-10T20:52:15Z
dc.date.available.fl_str_mv 2019-10-10T20:52:15Z
dc.date.issued.fl_str_mv 2019-03-14
dc.type.status.fl_str_mv info:eu-repo/semantics/publishedVersion
dc.type.driver.fl_str_mv info:eu-repo/semantics/masterThesis
format masterThesis
status_str publishedVersion
dc.identifier.uri.fl_str_mv https://repositorio.ufpe.br/handle/123456789/34460
dc.identifier.dark.fl_str_mv ark:/64986/0013000006qv1
url https://repositorio.ufpe.br/handle/123456789/34460
identifier_str_mv ark:/64986/0013000006qv1
dc.language.iso.fl_str_mv por
language por
dc.rights.driver.fl_str_mv Attribution-NonCommercial-NoDerivs 3.0 Brazil
http://creativecommons.org/licenses/by-nc-nd/3.0/br/
info:eu-repo/semantics/openAccess
rights_invalid_str_mv Attribution-NonCommercial-NoDerivs 3.0 Brazil
http://creativecommons.org/licenses/by-nc-nd/3.0/br/
eu_rights_str_mv openAccess
dc.publisher.none.fl_str_mv Universidade Federal de Pernambuco
dc.publisher.program.fl_str_mv Programa de Pos Graduacao em Ciencia da Computacao
dc.publisher.initials.fl_str_mv UFPE
dc.publisher.country.fl_str_mv Brasil
publisher.none.fl_str_mv Universidade Federal de Pernambuco
dc.source.none.fl_str_mv reponame:Repositório Institucional da UFPE
instname:Universidade Federal de Pernambuco (UFPE)
instacron:UFPE
instname_str Universidade Federal de Pernambuco (UFPE)
instacron_str UFPE
institution UFPE
reponame_str Repositório Institucional da UFPE
collection Repositório Institucional da UFPE
bitstream.url.fl_str_mv https://repositorio.ufpe.br/bitstream/123456789/34460/5/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf.jpg
https://repositorio.ufpe.br/bitstream/123456789/34460/1/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf
https://repositorio.ufpe.br/bitstream/123456789/34460/2/license_rdf
https://repositorio.ufpe.br/bitstream/123456789/34460/3/license.txt
https://repositorio.ufpe.br/bitstream/123456789/34460/4/TESE%20Filipe%20Rafael%20Gomes%20Varj%c3%a3o.pdf.txt
bitstream.checksum.fl_str_mv 9ab5c4ae5c67a30abb9c05ce4385d458
85986fe5d5feac320b570758051d5219
e39d27027a6cc9cb039ad269a5db8e34
bd573a5ca8288eb7272482765f819534
bd67fd6ea77ba55f087407be7db14f6e
bitstream.checksumAlgorithm.fl_str_mv MD5
MD5
MD5
MD5
MD5
repository.name.fl_str_mv Repositório Institucional da UFPE - Universidade Federal de Pernambuco (UFPE)
repository.mail.fl_str_mv attena@ufpe.br
_version_ 1814448193121812480