虚拟机运行时数据区

Java虚拟机会在执行Java程序的过程中把它所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域依赖用户线程的启动和结束而建立和销毁。
区域划分如下图所示:


[img]http://dl2.iteye.com/upload/attachment/0105/1879/5adbb350-d14e-3fd4-9474-0ee929c0cc1a.jpg[/img]

其中由所有线程共享的数据区是堆和方法区,线程隔离的数据区是程序计数器、虚拟机栈和本地方法栈。

1)程序计数器
它是一块较小的内存空间,可以看成是当前线程执行的字节码的行号指示器,它是线程私有的。
2)虚拟机栈
它也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
栈帧的结构如下图所示:


[img]http://dl2.iteye.com/upload/attachment/0105/1881/c4ba328c-2a6d-3564-8a88-5da6bc85a8bb.jpg[/img]


局部变量表存放了基本数据类型,对象引用和retunAddress类型。局部变量表所需的内存空间在编译期就确定了,运行期间不会改变局部变量表的大小。

局部变量表占用的空间是可以复用的,例如:
public void test1(){
{
long a = 1;
}
long b = 2;
}
public void test2(){
long a = 1;
long b = 2;
}

test1方法中由于定义b的时候a的作用域已经失效,所以b可以复用a的空间,所以test1方法的局部变量表空间大小是:2(long型占2个)+1(this) =3
test2方法a和b的作用域相同,所以b不能复用a的空间,所以test2的局部变量表空间大小是:2(a)+2(b)+1(this)=5。


HotSpot虚拟机中可以通过-Xss来设置栈的大小,栈的大小决定了方法调用的可达深度,如果有递归调用不要设置的太小,多线程下-Xss大的话,JVM占用的内存也就相应的变大。


3)本地方法栈
本地方法栈同虚拟机栈相似,他们的区别是虚拟机栈是为Java方法服务,而本地方法栈是为本地native方法服务的。


4)Java堆
Java堆是虚拟机所管理的内存中最大的一块,Java堆是所有线程共享的内存区域,几乎所有的对象实例都在这里分配内存。对于HotSpot虚拟机来说,Java堆内存又可以进一步划分为:新生代和老年代,新生代又可以进一步划分为Eden空间和From、to两个Survivor空间,之所以这样划分是为了更好的做垃圾收集,根据Java对象的特点,可以针对不同的区域采用不同的垃圾回收算法。
可以通过参数-Xms --初始堆大小 -Xmx --最大堆大小 -Xmn --新生代大小,设置各个区域的大小。
另外为了避免多线程分配堆空间临界点的同步问题,又为每个线程划分了私有的分配缓冲区TLAB(Thread Local Allocation Buffer)。

Java通过根搜索方法来判定对象是否存活,也就是通过一系列的GC Roots对象作为起始点,从他们开始往下搜索,当对象到GC Roots不可达时,则判定对象已死,可以被回收了。

Java中可以作为GC Roots的对象有:
a.虚拟机栈(栈帧中的本地变量表)中引用的对象。
b.方法区中类静态属性引用的对象。
c.方法区中常量引用的对象。
d.本地方法栈中引用的对象。
5)方法区
方法区也是线程共享的内存区域,用于存储虚拟机加载的类信息、静态变量、常量等数据。这个区域也会做GC。在HotSpot中方法区也称为永久代。
-XX:PermSize --永久代初始大小 -XX:MaxPermSize --永久代最大值

类的回收需要同时满足下面3个条件:
a.该类的所有实例都已经被回收,即Java堆中不存在任何该类的实例。
b.加载该类的ClassLoader已经被回收。
c.该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
6)运行时常量池
运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。

7)直接内存
直接内存不属于运行时数据区中,它直接分配堆外内存。
可以通过如下代码分配:
ByteBuffer.allocateDirect(128*1024*1024);


《深入理解Java虚拟机》 -周志明
《Java性能优化》 -葛一鸣
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值