1、程序计数器是线程私有的,每一个线程都有属于自己的一个程序计数器,程序计数器的作用就是记录当前线程执行字节码的指令地址,
也正是因为每一个线程都有自己的程序计数器,所以在线程切换的时候才可以正确的知道自己线程上次执行的指令地址
2、栈。也是线程私有的,每一个方法在运行的时候虚拟机都会为他创建一个栈指针,一个方法从开始执行到执行结束,也是一个栈指针从入站到出栈的过程,这个指针为什么能确定呢?因此再栈里存放着当前方法执行的一些信息,如局部变量表,方法的入口出口等信息,局部标量表存放着编译器可知道所有基本数据类型变量,由于这些类型的长度都是固定的,所以一个方法执行,那么这些变量在栈中所占有的空间也就是固定的,因为也就可以根据所需的空间总数来决定栈指针。当然,当前虚拟机栈都是可以扩充的,当需要扩充的容量,大于虚拟机的内存的时候,就会抛出栈溢出异常信息。
3、本地方法栈和虚拟机栈作用一样,只是他是存储本地native方法的内存区域
4、堆。是java虚拟机内存中最大的一块内存,这个内存主要的特点就是被所有的线程所共享的。垃圾回收期的主要作用就是在这块内存上进行对象回收,
当然,堆里面存放对象和数组,这些大家都知道。当然,对还可以细分,无论分的如何细都是为了方便管理,但是存放内容上没有改变。堆里面的内存也是可以不连续的,就像我们的硬盘。当然,堆的大小也可以选择固定大小或者扩展大小,这个和栈是类似的。
5、方法区。和堆一样,也是所有线程共享的区域内存。它里面主要存放已经被虚拟机加载的类信息,常量,静态变量,即使编译器编译后的代码等等,所以这也是为什么对于全局的变量,进行多线程访问的时候需要维护类的安全性的原因。它相对于堆除了内存可以不连续和内存可以固定大小或扩展之外,他还可以选择垃圾回收器对这个区域不进行回收。当然,也并不是说这个区域的数据都是永久存在的,只是垃圾回收期对这个区域的垃圾回收,并不是让人满意的,垃圾回收器主要只是回收这个区域的常量池回收和类型的卸载作用。下面我们就讲一下运行期常量池
6、运行期常量池。他是方法区的一部分,Class文件中除了存放类的版本,字段,方法,接口等信息之外,还会存放一样信息是常量池,用于存放编译器生成的各种字面量和符号引用,这部分内容,在方法被加载之后存放到常量池中。当然也可以在运行的时候放入运行期常量池中。我们最常接触的就是字符串常量池,调用string的intern方法,就可以把一个字符串放到常量池里面,如String a = new String('abc'),此时我们都知道abc存在在堆中因为是用new关键字创建的,如果我们调用a.intern()方法,那么他就会在常量池中创建一个字符串‘abc’。
通过以上分析,我们需要重点知道的是对于堆和方法区,当然还有方法区包含的运行期常量池,他们都是现成共享的。方法区存放的是class的相关信息。除了计数器之外,其他的内存都有可能发生溢出的现象,我们可以通过手动设置虚拟机内存的大小来测试什么时候发生异常。
java 虚拟机内存总结
最新推荐文章于 2020-11-17 08:52:49 发布