方法区:存放着虚拟机已经加载的类信息、常量、静态变量等数据,是线程共享的。人们习惯将方法去称为“永久区”,这仅仅是因为hotspot虚拟机将GC分代回收扩展到了方法区的缘故。
运行时常量池是方法区的一部分,Class文件除了有类的字段,类型,方法,接口等信息之外,还有一项是常量池,用于存放编译期生成的字面量和符号引用等,这些内容在类加载的时候就被存放在方法区的运行时常量池里面;Java虚拟机规范规定,当方法区无法满足内存需求的时候,就会抛出OutOfMemeryError异常
堆:java堆是虚拟机管理的最大内存区域,是被所有线程共享的。Java堆存放着对象实例数据,虚拟机规范中指出,所有的对象实例以及数组都要在堆上分配,但随着技术的发展,这种说法已经逐渐的变得不那么绝对了。虚拟机规范规定,当java堆不能满足对象实例分配,并且堆无法再扩展,则会抛出OutOfMemeryError异常
虚拟机栈:描述这java方法执行的内存模型,每个方法执行的时候会创建一个栈帧,用于存放局部变量表(存放着基本数据类型和对象引用),操作数栈,方法出口等信息。方法执行直到完成的过程,就对应着一个栈帧的出栈和入栈过程。Java虚拟机栈是线程独立的,栈的生命周期也就是线程的生命周期。虚拟机规范规定了两种异常的情况,第一、线程的请求深度超过了虚拟机规定的最大栈深度,则抛出StackOverflowError异常;第二、如果栈可以动态的扩展,在扩展的时候没能申请到足够的空间,则抛出OutOfMemeryError异常
本地方法栈:此栈的作用域虚拟机栈非常相似,其区别不过就是java虚拟机栈执行的是java方法,而本地方法栈执行的是java需要的native服务。因此它也有上述两种异常的情况
程序计数器:可以简单的认为,程序计数器是字节码的指示器;计数器记录的是正在执行的虚拟机字节码的地址,如果是执行本地方法,则改计数器为空
直接内存:这部分是java虚拟机规范没有定义的,称为堆外内存;直接内存不受java堆内存大小的限制,但是如果堆内存和直接内存的总和大于机器的内存,同样会抛出异常。
常见配置
-Xms:设置虚拟机内存堆的初始大小,缺省是字节为单位;eg.-Xms128M
-Xmx:设置虚拟机内存堆的最大值,缺省也是以字节为单位;eg.-Xmx512M
-Xss:设置虚拟机栈的大小,设置方法同上
-XX:PermSize:设置非堆内存初始内存(即方法区内存,方法区也叫Non-Heap);eg.-XX:PermSize=64M
-XX:MaxPermSize:设置非堆内存最大内存;eg.-XX:PermSize=128M
-XX:MaxDirectMemorySize:设置直接内存容量,没指定,则与堆最大值一样;eg.-XX:MaxDirectMemorySize=128M