本文内容来源于互联网,并稍作整理。
JVM主要包括两个子系统和两个组件
一、子系统
1、Class loader(类装载器)子系统
2、Execution engine(执行引擎)子系统
二、组件
1、Native interface(本地接口)组件
2、Runtime data area(运行时数据区域)组件—JVM内存
Runtime data area包括五部分
①、Heap
②、Method Area(存储装载的类信息)
③、Java Stack
④、Program Counter(程序计数器)
⑤、Native method stack(本地方法栈)
其中①Heap和②Method Area被所有线程共享使用,③、④、⑤ 以线程为粒度,每个线程独自拥有。
①、Heap
一个JVM实例只存在一个Heap空间,每个Java程序独占一个JVM实例。一个Java程序的多个线程共享同一个堆空间。
Heap分为New Generation、Old Generation。
New Generation
用于存放程序中新建的对象,由Eden Space和两块Survivor Space构成。通过-Xmn参数来指定其大小。
Old Generation
存放程序中经过几次垃圾回收还存活的对象。占用的内存大小即为-Xmx指定的大小减去-Xmn指定的大小。
Permanet Generation
存放静态文件,持久代对垃圾回收没有显著影响,但有些应用可能动态生成或者调用一些class,例如Hibernate等,此时需要设置一个较大持久代空间来存放。持久代大小通过-XX:MaxPermSize= 进行设置。
②、Method Area(存储装载的类信息)
(1)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,可见方法区域的重要性,同样,方法区域也是全局共享的,在一定的条件下它也会被GC,当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
④、Program Counter(程序计数器)
PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。
⑤、Native method stack(本地方法栈)
对于运行中的Java程序而言,会用到和本地方法相关的数据区。调用本地方法时,不受虚拟机限制。
异常与参数
1、java.lang.OutOfMemoryError:java heap space
New Generation和Old Generation空间不足,参数-Xms和-Xmx。
2、java.lang.OutOfMemoryError: Java Permanent Space
永久存储区空间不足,-XX:PermSize和-XX:MaxPermSize
-Xss 单个线程堆栈大小值;JDK1.5以后每个线程堆栈大小为1M,以前为256K。
-XX:+UseParNewGC可用来设置年轻代为并发收集(多cpu),如果服务器多cpu,开启此参数多cpu并发收集垃圾。
+UseParallelGc,选择垃圾收集器为并行收集器。此配置仅对年轻代有效。
-XX:ParallelGCThreads 年轻代并行垃圾收集的前提下的线程数,增加并发度。最好与处理器数目相等。
-XX:PermSize 应用服务器启动时,永久存储去的初始内存大小。
-XX:MaxPermSize 应用运行中,永久存储去的极限值,默认值为64M。
生产环境-XX:PermSize和-XX:MaxPermSize强烈推荐值设为相同
-Xms 启动应用时,JVM堆空间的初始大小值,默认值是物理内存的1/64但小于1G。
-Xmx 应用运行中,JVM堆空间的极限值,默认值是物理内存的1/4但小于1G。为了不消耗扩大JVM堆控件分配的开销,参数和-Xms这两个值设为相等,考虑到需要开线程,将此值设为内存的80%。
-Xmn 此参数硬性规定堆空间的新生代空间大小,推荐设为堆空间大小的1/4。