O Java ao contrário do C possui um layout de memória muito bem definido e especificado pela JSR 133. Estava estudando sobre isso e me deparei com a seguinte duvida:
Na wikipedia diz:
[quote]
Heap
The Java Virtual Machine heap is the area of memory used by the JVM (and specifically HotSpot) for dynamic memory allocation[11]. The heap is split up into “generations”:
* The Young generation stores short-lived Objects that are created and immediately Garbage collected.
* Objects that persist longer are moved to the Old generation (also called the Tenured generation).
* The Permanent generation (or permgen) is used for class definitions and associated metadata.[12][13].
There was originally no permanent generation, and Objects and classes were just stored together in the same area. But as class unloading occurs much more rarely than Objects are collected, moving class structures to a specific area allows significant performance improvements[12].[/quote]
O heap da JVM é dividido em três áreas, sendo uma delas a permgen destinada a definições de classe e metadados associados. Logo em seguida é dito que não existe tal área e que objetos e classes são armazenados na mesma área, contudo o descarregamento de classes da memória é raro se comparado com a coleta de objetos.
Em outras literaturas vejo o conceito de Method Area
[quote]
The method area and the program counter
The method area is where the bytecodes reside. The program counter always points to (contains the address of) some byte in the method area. The program counter is used to keep track of the thread of execution. After a bytecode instruction has been executed, the program counter will contain the address of the next instruction to execute. After execution of an instruction, the JVM sets the program counter to the address of the instruction that immediately follows the previous one, unless the previous one specifically demanded a jump. [/quote]
Ou seja a Method Area é onde o código em linguagem intermediária, o bytecode é armazenado. Ou seja não é no heap muito menos em permgen.
There was originally no permanent generation, significa “originalmente não existia uma região permgen” (perceba que o método existir está no passado).
Ou seja, no inicio era assim, e então perceberam que descarregar classes era uma coisa rara, e mover essas estruturas (as classes) para uma região separada (o permgen) representou um grande ganho de performance.
There was originally no permanent generation, and Objects and classes were just stored together in the same area. But as class unloading occurs much more rarely than Objects are collected, moving class structures to a specific area allows significant performance improvements[12].
era:
Originalmente, não havia uma região permgen, e os Objetos e classes eram simplesmente armazenados na mesma área. Mas, como a carga de classes ocorre muito mais raramente que a coleta de objetos, mover a estrutura de classes para uma área específica permitiu uma melhoria significativa da performance[12]."
Acho que em todas as bibliografias de SO que li, somente a área de dados é considerada “área de memória” da aplicação. Enquanto a área de código, embora também sendo uma área de memória, não é considerada assim. Talvez pq na maior parte das aplicações clássicas a área de código fosse imutável e, no caso de alguns SOs (como o Windows) ficasse até mesmo num setor separado da aplicação.
Também é bom lembrar que tradicionalmente dava-se sempre o mínimo de controle por parte da aplicação possível para essa área. Geralmente, a carga da área de código é feita pelo SO, sem interferência direta da aplicação. Dlls e classloaders tornaram mudaram um pouco dessa realidade, mas acho que a distinção permanece.
Então o conceito de Method Area existe somente no escopo da máquina virtual, mas no final das contas, no S.O., isto tudo está no heap da JVM.
O Java funciona 100% em dynamic loading ou seja todo o código é carregado na memória em tempo de execução. Classes são carregadas quando necessário e podem ser recuperadas até pela rede. O código entrante é verificado antes de ser passado para o interpretador para execução.
Estava lendo sobre o problema FBI (Fragile Binary Interface) comum na linguagem C++ onde objetos foram construídos em cima do conceito de structs que armazenam uma variedade de informações relacionadas em uma única parte de memória. Essas partes são acessadas rastreando-se o ponto inicial e os offsets de memória entre as partes. A única mudança significativa foi a introdução de um campo a mais que lista os varios métodos do objeto, então aquele struct possui seus próprios dados e funções. Quando compilados os offsets são usados para acessar tanto dados quanto código.
Isso pode ocasionar problemas em programas que são construídos utilizando bibliotecas. Se o autor da biblioteca altera o tamanho ou a disposição dos campos públicos do objeto, os offsets são então inválidos e o programa não irá mais funcionar, tipificando-se o problema FBI.
A forma em que o Java resolve isso está explicito aqui:
Uma classe é unicamente identificada na JVM usando seu nome full qualified com a instancia do ClassLoader que carregou essa classe. O interpretador rescreve os offsets numericos de acordo com a disposição dos membros do objetos. Ou seja, tudo é realizado dinamicamente.
Classes no Java possuem representação em tempo de execução. Se há uma classe de nome Class, há uma instância que contém suas definições.
E quando foi que eu falei que vai? Acho que você tem um problema sério em interpretar textos começados com expressões do tipo “originalmente”, “tradicionalmente”, etc. auehueheauuea
Como eu falei, talvez a distinção das áreas de memória ainda exista só por uma questão histórica. E dlls e classloaders (como os do java) obviamente não são enquadrados nesse caso.
De qualquer forma, para a maior parte das aplicações, a área de métodos ainda parece estática (mesmo sendo, de fato dinâmica, mas a carga de classes é automática e garantida). Fica como exceções apenas aplicações que manipulem diretamente classloaders.
Só estava explicando pq fazem distinção nos termos, e geralmente não se inclui a área de código como “área de memória da aplicação”.