一、写在前面
本文仅作为我的学习和思考笔记,其中有表述错误的地方,欢迎大家拍砖指正。
本文所有描述均基于SUN的HotSpot虚拟机。
JVM版本为1.6U21
本系列会从JVM最基本的概念模型,逐步总结JVM的工作方式,GC,调优等内容,尽量做到以最通俗简单的语言描述清楚JVM相关内容以及我的学习总结。
二、JVM运行时各数据区域
在我们实际开发过程中,绝大多数程序员关心的只有代码的运动时状态,管理运行时数据区也是JVM的主要工作。JVM的运行时数据区如下图:
堆(heap)
JAVA程序员最需要关注的区域。堆的主要作用是为我们的对象实例分配内存,即所有通过new关键词生成的对象都将在这里被实际分配内存。
堆内存根据对象生命同期的长短被分为了几个不同的区别,分别是:
- Eden区:绝大部分对象都在这里被实例化,有些较大对象可能会被直接分配到OLD区(依据虚拟机参数决定)
- S0、S1区:被一次young GC回收后,仍还存活的对象会被移动到这两个区(具体如何移动在GC篇会说)
- OLD区:经过了几次young GC后仍然存活的对象会被移动到这个区(某些大对象会被直接分配到该区,依据虚拟机参数决定)
Eden,S0,S1被统称为新生代(相对于OLD区而得名)
绝大部分内存溢出都是发生在堆上,后面总结GC篇和调优篇再慢慢说
永久代(Perm Gen)
在JVM规范中并没有永久代的概念,永久代是HotSpot特有的,对应JVM规范的方法区(method area)
永久代主要的作用是存放被JVM加载的类信息,常量,静态变量等
永久代也会被GC,但效果会比较差
虚拟机栈(VM Stacks)
虚拟机栈是线程私有的,每个线程开始后,都会创建一个虚拟机栈,用来存放我们使用的一些局部变量,对象引擎,基本数据类型,方法出口等跟线程有关的数据。
虚拟机栈里存入的数据基本上都是在编译时可知的数据类型。
本地方法栈(Native Method Stacks)
在JVM规范中,本地方法栈的作用的虚拟机栈是类似的,只不过本地方法栈是执行Native方法
在SUN的HotSpot虚拟机中,本地方法栈被合并到了虚拟机栈,所以大家可以忽略这个东西了
程序记数器
主要记录线程执行指令的偏移量
直接内存(Direct Memory)
这块内存比较特别,它不属于JVM在运行时的管理范畴,是一块堆外内存,主要是当执行了一些外部程序或通过JAVA内部方法操作外部数据时使用的内存
这部分内存不受JVM限制,但受操作系统进程和物理内存大小的限制