JVM:又叫java虚拟机,JVM是为了项目使用软件在不同操作系统中,模拟相同环境而诞生的。
JVM可以分为5大区:
1. 方法区:
方法区是线程共享的,主要存储虚拟机加载的类信息,常量,静态变量等数据,在jdk1.6之前,方法区里面还包含了运行时常量池,Class常量池和串池(字符串常量池),在jdk1.7中,串池被移到了堆中。
Class常量池:主要存放编译器生成的各种字面量和符号引用。
字面量:文本字符串,八种基本类型的值,final修饰的常量
符号引用:类和接口的权限定名,字段名称和描述符,方法名称 和描述符。
运行时常量池:在类加载执行时,JVM会把Class常量池中的内容放到运行时常量池中。所以运行时常量池中也存储各种字面量和符号引用。
方法区是线程共享的,会内存溢出。
2. 虚拟机栈:
虚拟机栈是线程私有的,也就是说每一线程都会有一个属于自己的虚拟机栈。生命周期与线程相同。存放的是java代码中的基本数据类型,对象的引用变量,出栈,入栈,等
3. 本地方法栈
本地方法栈是线程私有的。因为大部分的JVM是C和C++写的。所以本地方法(native)中栈存放的是本地方法中的基本数据类型,对象的引用变量等。其实虚拟机栈和本地方法栈运行的原理是相似的,一个是存储java方法中相关数据,一个是存储本地方法中的数据
4. 堆
堆是所有线程共享的,是JVM中最大的一块区域,存储的是对象类型数据.
比如:int[] arr = new int[3];当程序执行这行代码时,这时JVM会在堆区分配一个长度为3的数组对象。也就是说new int[3] 是存放在堆区的,而int[] arr 是存放在栈区的,这个栈区实际存放的是指向堆区数组的地址。
堆是垃圾收集器(GC)主要管理的区域,也被成为GC堆。堆中还可以细分为新生代,老年代等。
5. 程序计数器
程序计数器是一块较小的内存空间。当程序在执行java代码时,而这个程序计数器表示的是当前代码的运行到的某一位置。而字节码解释
器是通过改变这个程序计数器的值来选取下一条需要执行的命令。
6. 类加载
概念:当JVM第一次使用类时,JVM会根据环境变量classpath找到.class文件,将.class文件中与类相关的所有语法存在JVM的内存中。
类加载只发生一次。
触发类加载的时机:创建对象,调用静态属性,调用静态方法,创建
子类对象
类加载过程就相当于人的大脑第一认识一个新的物种时,或者一个新
的朋友时的过程。当你认识一个新朋友之前,是不知道他叫什么名字,
而当他向你做自我介绍时,你的大脑中会将这个人的特征,面貌,名
字等存入脑海中。这个过程就类似与JVM中的类加载。
7.总结:这5大区中只有堆区和方法区是线程共享的,而只有程序计数器不会内存溢出