Have you ever wondered how the permanent generation fits into our
generational system? Ever been curious about what's in the permanent
generation. Are objects ever promoted into it? Ever promoted out?
We'll you're not alone. Here are some of the answers.

Java objects are instantiations of Java classes. Our JVM has an internal
representation of those Java objects and those internal representations
are stored in the heap (in the young generation or the tenured generation).
Our JVM also has an internal representation of the Java classes and those
are stored in the permanent generation. That relationship is shown in 
the figure below.

The internal representation of a
Java object and an internal representation of a Java class are very
similar. From this point on let me just call them Java objects and Java
classes and you'll understand that I'm referring to their internal
representation. The Java objects and Java classes 
are similar to the extent that during a garbage collection both
are viewed just as objects and are collected in exactly the same way. So 
why store the Java objects in a separate permanent generation? Why not just
store the Java classes in the heap along with the Java objects?

Well, there is a philosophical reason and a technical reason. The 
philosophical reason is that the classes are part of our JVM implementation
and we should not fill up the Java heap with our data structures. The
application writer has a hard enough time understanding the amount 
of live data the application needs and we shouldn't confuse the issue
with the JVM's needs.

The technical reason comes in parts.
Firstly the origins of the permanent generation predate my joining the team
so I had to do some code archaeology to get the story straight (thanks
Steffen for the history lesson).

Originally there was no permanent generation. Objects and classes
were just stored together.

Back in those days classes were mostly static. Custom class loaders were
not widely used and so it was observed that 
not much class unloading occurred. As a performance optimization 
the permanent generation was created and classes were put into it.
The performance improvement was significant back then. With the amount
of class unloading that occur with some applications, it's not clear that
it's always a win today.

It might be a nice simplification to not have a permanent generation, but
the recent implementation of the parallel collector for the tenured
generation (aka parallel old collector)
has made a separate permanent generation again desirable. The issue
with the parallel old collector has to do with the order in which
objects and classes are moved. If you're interested, I describe this
at the end.

So the Java classes are stored in the permanent generation. What all 
does that entail? Besides the basic fields of a Java class there are

  • Methods of a class (including the bytecodes)
  • Names of the classes (in the form of an object that points to a string also in the permanent generation)
  • Constant pool information (data read from the class file, see chapter 4 of the JVM
    specification for all the details).
  • Object arrays and type arrays associated with a class (e.g., an object array
    containing references to methods).
  • Internal objects created by the JVM (java/lang/Object or java/lang/exception 
    for instance)
  • Information used for optimization by the compilers (JITs)

That's it for the most part. There are a few other bits of information that
end up in the permanent generation but nothing of consequence in terms of size. All these are allocated in the permanent generation and stay
in the permanent generation. So now you know.

This last part is really, really extra credit.
During a collection the garbage collector needs
to have a description of a Java object (i.e., how big is it and what
does it contain). Say I have an object X and X has a class K.
I get to X in the collection and I need K to tell me what X 
looks like. Where's K? Has it been moved already?
With a permanent generation during a collection we move the
permanent generation first so we know that all the K's are in
their new location by the time we're looking at any X's.

How do the classes in the permanent generation get collected while the
classes are moving? Classes also have classes that describe their content.
To distinguish these classes from those classes we spell the former klasses.
The classes of klasses we spell klassKlasses. Yes, conversations around the
office can be confusing. Klasses are instantiation of klassKlasses so
the klassKlass KZ of klass Z has already been allocated before Z can be 
allocated. 
Garbage collections in the permanent generation 
visit objects in allocation order and that allocation order is 
always maintained during the collection. That is, if A is allocated 
before B then A always
comes before B in the generation. Therefore if a Z is 
being moved it's always the case that KZ has already been moved.

And why not use the same knowledge about allocation order to 
eliminate the permanent generations even in the parallel old
collector case?
The parallel old collector does maintain allocation order of
objects, but objects are moved in parallel. When the collection
gets to X, we no longer know if K has been moved. It might be
in its new location (which is known) or it might be in its
old location (which is also known) or part of it might have
been moved (but not all of it). It is possible to keep track
of where K is exactly, but it would complicate the collector
and the extra work of keeping track of K might make it a performance
loser. So we take advantage of the fact that classes are kept in the permanent 
generation by collecting the permanent generation before collecting
the tenured generation. And the permanent generation is currently collected serially.

Presenting the Permanent Generation相关推荐

  1. JVM年轻代(young generation)老年代(old generation tenured)持久代(permanent generation)GC...

    关于jvm内存代,看到这篇文章,转发下 链接地址 ---多谢 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent ...

  2. JVM年轻代(young generation)老年代(old generation tenured)持久代(permanent generation)GC

    关于jvm内存代,看到这篇文章,转发下 链接地址 ---多谢 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent ...

  3. 记一次JVM调优(Permanent Generation)

    最近在一次搭建公司系统运行环境的时候tomcat总是报出 java.lang.OutOfMemoryError PermGen space 的问题,即内存溢出 在解决这个问题的时候 一.问题解决 此处 ...

  4. 为什么JDK 1.8中不再有永久代(permanent generation)

    1.什么是永久代 只有 HotSpot 才有 "PermGen space",而对于其他类型的虚拟机,如 JRockit(Oracle).J9(IBM) 并没有"Perm ...

  5. JVM相关概念和异常类型

    转载请注明出处 http://www.paraller.com 原文排版地址 点击获取更好阅读体验 概述 基本类型.对象的引用在栈内存中操作, 对象类型在堆内存中操作, 特点:栈容量小,速度快:堆是容 ...

  6. Tomcat内存溢出解决方法

    Java内存溢出详解 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap space ----JVM Heap(堆)溢出 JVM在 ...

  7. Tomcat 调优及 JVM 参数优化

    Tomcat 本身与 JVM 优化 Tomcat:调整Server.xml JVM:bat启动服务方式的话修改catalina.bat 服务式启动的话参考:http://www.cnblogs.com ...

  8. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  9. java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得

    该文章出自:http://www.cnblogs.com/hucn/p/3572384.html 分析工具:http://www.blogjava.net/jjshcc/archive/2014/03 ...

最新文章

  1. 机器学习中过拟合、欠拟合与方差、偏差的关系是什么?
  2. 【Android】Handler详解
  3. Tableau实战系列数据连接及数据准备
  4. p1605迷宫(DFS应该注意的问题)
  5. PowerShell 2.0 实践(十一)管理 TFS 2010 (2)
  6. css3 object-fit详解
  7. 数据可视化系统在哪些行业中应用
  8. Fortran77基础
  9. 21天学通C语言-学习笔记(10)
  10. 从零开始学Java——基础篇
  11. 10.16作业 如鹏
  12. vue核心之虚拟DOM(vdom)与真实DOM页面渲染过程
  13. Java 的 IDEA 神级插件!
  14. Golang库 - viper读取配置文件
  15. php 生僻字 拼音,PHP汉字转拼音(支持生僻字)
  16. win10家庭版如何使用远程桌面功能
  17. fetch用英语解释_fetch的用法总结大全
  18. Learning English From Android Source Code:1
  19. (一)android 桌面悬浮窗 录屏源码放送
  20. Character n is neither a decimal digit number, decimal point, nor “e“ notation exponential mark.

热门文章

  1. Linux文件系统与日志分析(inode、inode节点耗尽故障处理、文件备份和恢复、日志文件管理)
  2. apriori算法代码python_Apriori算法的Python实现
  3. android studio开关按钮,Android studio实现滑动开关
  4. android opencv 识别文字_基于SpringBoot的车牌识别系统(附项目地址)
  5. activemq 控制台怎么看生产信息_Jmeter中间件处理-ActiveMQ
  6. mysql 查看索引深度_mysql 学习 - 索引深度理解
  7. linux的 vi编辑器在哪,Linux Vi编辑器的使用
  8. 移植 stm32f7_移植zephyrOS到正点原子apollo STM32F767上
  9. 云计算机教室安装学生软件,新东方云教室1.6版本
  10. python实现多线程的三种方法threading.Thread(模块)的继承实现和函数实现;以及concurrent.futures模块的线程池实现