0.概论
推荐书目:深入理解Java虚拟机
java虚拟机内存主要分为三部分:java虚拟机栈,java堆,静态方法区
1.java虚拟机栈
其中java虚拟机栈就是我们俗称的栈内存,其中主要存放的是8种基本类型和对象的引用,这一部分为线程私有部分,当请求的栈深度大于java虚拟机栈所允许的深度,jvm将抛出StackOverflowError异常
java中的引用可以理解为c++中的指针
2.java堆
java堆空间主要存放的就是java程序运行过程中所产生的对象,而如果需要使用对象则需要先从栈内存中拿到引用,通过引用来指向对内存中的对象,而通过引用来操作对象也有两种方式(句柄方式和直接指针),其中java堆是各个线程共享的,因此在操作对象的过程中我们需要使用锁来锁住对象,避免多线程中产生的数据不一致问题,当对象大小总和超过jvm分配的对内存大小时jvm会抛出OutOfMemoryError异常
图中的对象实例数据就是jvm中对象的成员变量等每个对象独有的内容,而对象类型数据就是类方法等所有对象相同的部分
堆内存中其实还可以再继续细分,可以分为年轻代和老年代,这两代应该通过名字十分好理解,年轻代一般存放年纪较小的,刚生成没多久的对象,而老年代则主要存放年纪较大,生成较久的对象(关于java堆中的具体内容和jvm的gc策略后面还会有文章详细讲解)
3.静态方法区
从该区域的名字大家其实就可以大概看出本区域存储的内容了,即主要存储的是常量、静态变量和方法,还有一部分为jvm加载的类的信息(即.class文件),这一部分为线程共享的(因为每个线程都可以同时调用同一个方法嘛)
4.其他部分
啊嘞嘞?不是说jvm主要分为3个区域么?对,但是要注意是主要,其实jvm还存在几个经常被人忽略的区域,即为:本地方法栈,程序计数器
程序计数器:当前线程执行字节码的行号指示器(这是官方解释,其实就是执行到代码的行号),由于每个线程执行到的代码行号都不同,因此这一部分肯定是线程私有的啦
本地方法栈:主要为虚拟机使用native方法服务
5.直接内存的使用
在java1.4中引入了非阻塞IO模式,即NIO,在我们使用NIO时会通过native方法分配直接内存,避免在Java堆与native堆中来回复制数据,提高性能