java JVM
1 .java文件 ------> 编译器 --------> .class文件 ------> jvm----->机器码
JVM分为几块区域
1.Class Loader类加载器
负责加载.class文件,定位和导入.class文件
验证导入类的正确性
为类分配初始化内存
2.Native Interface本地接口
初衷是为了融合C/C++程序,做法是在内存中开辟一块区域处理标记为native的代码,在Native Method Stack中登记native方法,在Execution Engine执行时加载native libraies
3.Execution Engine执行引擎
执行包在装在类的方法中的指令,即方法
4.Runtime data area 运行数据区
JVM内存,在计算机中开辟一块内存存储JVM需要用到的对象,变量等。运行区分为:方法区,虚拟机栈,本地方法栈,堆,程序计数器。
JVM调优主要是优化Heap堆和Method Area方法区,这两块是线程共享的数据区
a.Native Method Stack本地方法栈
登记native方法,在Execution Engine执行时加载native libraies
b.PC Register程序计数器
每个线程都有一个程序计数器,它是一个指针,指向方法区中的方法字节码(下一个要执行的指令),由执行引擎读取下一条指令,是一个非常小的内存空间。
c.Method Area方法区
方法区是被所有线程共享,所有字段和方法字节码,特殊的方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域
静态变量,常量,类信息,运行时常量池存在方法区,实例变量存在堆内存中
d.Stack栈
栈内存,是在线程创建时创建,它的生命周期是跟随线程的生命周期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题
基本类型的变量和对象的引用变量都是在函数的栈内存中分配
栈运行原理:“先进后出/后进先出”的原则
e.Heap堆
一个JVM实例只有一个堆内存。堆内存分为三部分:新生区,老年代,永久区
1.新生区是类的诞生,成长,消亡的区域。新生区分为两部分伊甸区(Eden space)和幸存者区(Survivor space),所有类都是在伊甸区中new出来的。幸存者区有两个0区和1区。
当伊甸区的空间用完时,程序又要创建对象,JVM的GC将对伊甸区进行垃圾回收(Minor GC),将伊甸区中剩余对象移动到幸存者0区,若0区也满了,则对该区进行GC回收,
然后移动到1区,如果1区也满了则移动到老年代区,如果老年区也满了,那么这时候会进行Major GC( Major GC除并发GC外均需对整个堆进行扫描和回收 ,又称FullGC),
如果老年区执行Full GC之后依然无法进行对象保存那么就会产生OutOfMemoryError
如果出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:
a.Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。
b.代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。
2.老年区,用于保存从新生区筛选出来的 JAVA 对象。
3.永久区,是一个常驻内存区域,用于存放JDK自身所携带的class,interface的元数据,存储运行环境所必须的类信息,此区域的数据是不会被GC回收,关闭JVM才会释放。
如果出现java.lang.OutOfMemoryError: PermGen space,说明是Java虚拟机对永久代Perm内存设置不够。原因有二:
a.程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。
b.大量动态反射生成的类不断被加载,最终导致Perm区被占满。
jdk1.6以及之前:常量池分配在永久区
jdk1.7 已经逐步去除永久区
jdk1.8及以后:没有永久区 java.lang.OutOfMemoryError: PermGen space,不会出现了
1 .java文件 ------> 编译器 --------> .class文件 ------> jvm----->机器码
JVM分为几块区域
1.Class Loader类加载器
负责加载.class文件,定位和导入.class文件
验证导入类的正确性
为类分配初始化内存
2.Native Interface本地接口
初衷是为了融合C/C++程序,做法是在内存中开辟一块区域处理标记为native的代码,在Native Method Stack中登记native方法,在Execution Engine执行时加载native libraies
3.Execution Engine执行引擎
执行包在装在类的方法中的指令,即方法
4.Runtime data area 运行数据区
JVM内存,在计算机中开辟一块内存存储JVM需要用到的对象,变量等。运行区分为:方法区,虚拟机栈,本地方法栈,堆,程序计数器。
JVM调优主要是优化Heap堆和Method Area方法区,这两块是线程共享的数据区
a.Native Method Stack本地方法栈
登记native方法,在Execution Engine执行时加载native libraies
b.PC Register程序计数器
每个线程都有一个程序计数器,它是一个指针,指向方法区中的方法字节码(下一个要执行的指令),由执行引擎读取下一条指令,是一个非常小的内存空间。
c.Method Area方法区
方法区是被所有线程共享,所有字段和方法字节码,特殊的方法如构造函数,接口代码也在此定义。简单说,所有定义的方法的信息都保存在该区域
静态变量,常量,类信息,运行时常量池存在方法区,实例变量存在堆内存中
d.Stack栈
栈内存,是在线程创建时创建,它的生命周期是跟随线程的生命周期,线程结束栈内存也就释放,对于栈来说不存在垃圾回收问题
基本类型的变量和对象的引用变量都是在函数的栈内存中分配
栈运行原理:“先进后出/后进先出”的原则
e.Heap堆
一个JVM实例只有一个堆内存。堆内存分为三部分:新生区,老年代,永久区
1.新生区是类的诞生,成长,消亡的区域。新生区分为两部分伊甸区(Eden space)和幸存者区(Survivor space),所有类都是在伊甸区中new出来的。幸存者区有两个0区和1区。
当伊甸区的空间用完时,程序又要创建对象,JVM的GC将对伊甸区进行垃圾回收(Minor GC),将伊甸区中剩余对象移动到幸存者0区,若0区也满了,则对该区进行GC回收,
然后移动到1区,如果1区也满了则移动到老年代区,如果老年区也满了,那么这时候会进行Major GC( Major GC除并发GC外均需对整个堆进行扫描和回收 ,又称FullGC),
如果老年区执行Full GC之后依然无法进行对象保存那么就会产生OutOfMemoryError
如果出现java.lang.OutOfMemoryError: Java heap space异常,说明Java虚拟机的堆内存不够。原因有二:
a.Java虚拟机的堆内存设置不够,可以通过参数-Xms、-Xmx来调整。
b.代码中创建了大量大对象,并且长时间不能被垃圾收集器收集(存在被引用)。
2.老年区,用于保存从新生区筛选出来的 JAVA 对象。
3.永久区,是一个常驻内存区域,用于存放JDK自身所携带的class,interface的元数据,存储运行环境所必须的类信息,此区域的数据是不会被GC回收,关闭JVM才会释放。
如果出现java.lang.OutOfMemoryError: PermGen space,说明是Java虚拟机对永久代Perm内存设置不够。原因有二:
a.程序启动需要加载大量的第三方jar包。例如:在一个Tomcat下部署了太多的应用。
b.大量动态反射生成的类不断被加载,最终导致Perm区被占满。
jdk1.6以及之前:常量池分配在永久区
jdk1.7 已经逐步去除永久区
jdk1.8及以后:没有永久区 java.lang.OutOfMemoryError: PermGen space,不会出现了