JVM内存结构
JVM在运行时将数据划分为了6个区域来存储
1、PC Register(PC寄存器):很小的内存区域。
主要作用:记录当前线程所执行的字节码的行号(标识)。
在jvm中多个线程的实现是通过轮流分配处理器(CPU)时间的方式来实现的,即在任何一个确定的时间里,在处理器的内核之后执行
一个线程的指令,因此为了线程(栈)等待结束需要恢复到正确的位置执行,
每条线程都有一个独立的程序计数器(PC寄存器)来记录当前指令的行号(标识)。计数器(PC寄存器)之间相互独立不影响,
这块内存为线程的独立内存(PC寄存器)。
2、jvm栈(线程私有)
在Sun JDK中可以通过-Xss来指定栈的大小。
介绍:
栈中存放基础数据类型,自定义对象的引用(非对象)
每个线程一个栈区,栈内数据私用,线程独享
栈分三部分:基本类型变量、执行环境上下文、操作指令区
优缺点:速度快,但是大小、生命周期固定,不灵活
3、本地栈
跟jvm栈非常相似,区别在于jvm栈为虚拟机执行Java方法服务,
而本地方法栈则为jvm使用到Native方法服务。
4、堆( Heap)
java堆是和应用程序关系最为密切的内存空间,几乎所有的对象都存放在堆上。
并且java堆是完全自动化管理的,通过垃圾回收机制,垃圾对象会被自动清理,而不需要显示的释放。
其大小通过-Xmx来控制,
-Xms为JVM启动时申请的最小Heap内存,默认为物理内存的1/64但小于1G,
-Xmx为JVM可申请的最大Heap内存,默认为物理内存的1/4,默认当空余堆内存小于40%时。
可通过-XX:MinHeapFreeRatio=来指定这个比例。
注: 当堆中需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
介绍:
堆中存放对象
jvm中只有一个堆区,各线程共享
优缺点:内存是动态的,生命周期不定GC自动回收,速度慢
5、 方法区域 (MethodArea)
也叫静态区,所有线程共享
存放 类的信息,常量和静态变量,即类被编译后的数据
包含的是在整个程序中永远唯一的元素,如:class,static变量
在Sun JDK中这块区域对应的为PermanetGeneration,又称为持久代,默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小。
6、直接内存
堆外内存,并非虚拟机数据区的一部分,可以分配的,大小受本机内存限制
与堆区相比,IO读写性能要优于堆区,频繁申请更耗费性能
堆内外内存比较:
直接内存的IO访问效率要高于非直接内存的访问效率
原因:
本地IO会直接操作直接内存,而非直接内存的话,会比直接内存多操作一步,堆内存copy到直接内存这步。