您的位置 首页 java

Java 虚拟机

java 运行时内存区域

内存区域分为以下几个:

  • 程序计数器
  • 虚拟机栈
  • 本地方法栈
  • 方法区

程序计数器

存储了下一个指令的地址,是 线程 私有的, 生命周期 与线程一样。

虚拟机栈

虚拟机栈是线程私有的,其生命周期与线程一样。
java在运行时,虚拟机栈会同时创建一个栈帧,用于存储
局部变量 操作数栈 动态连接 方法出口 等信息。

每当调用一个方法时,就会对应一个栈帧在虚拟机栈中从入栈到出栈。(调式的时候非常明显)

我们平常说的“栈”和“堆”,其中“栈”指定就是虚拟机栈,更具体的说是虚拟机栈中的“局部变量表”。

  • 局部变量表
     局部变量表中存放了基本数据类型( boolean byte char short 、int、long、float、double)、
    对象引用类型、returnAddress类型。
    
    局部变量表所需的空间是在编译期间完成的  
  • 局部变量槽(Slot)
 数据类型在局部变量表中的大小是按槽的个数决定的。比如:64位长度的long和double类型的数据会占用两个变量槽,其余的数据类型只占用一个。

槽相当于单位,一个槽大小是32比特或者64比特,槽的大小由虚拟机本身决定,不同的虚拟机的槽各不一样。  
  • 异常
 局部变量表中存在两种异常:

StackOverflowError异常:线程请求的深度大于虚拟机所允许的深度。

 OutOfMemory Error异常:如果 Java 虚拟机可以动态扩展,当栈扩展时无法申请到足够的内存会抛出此异常。  

本地方法栈

线程私有的。 虚拟机栈和本地方法栈的作用类似,其区别只是虚拟机栈为虚拟机执行Java方法( 字节码 )服务,而本地方法栈是为虚拟机使用到本地(Native)方法服务。

本地方法栈也会抛出OutofMemoryError异常和StackOverflowError异常

Java堆

线程共享

几乎所有的对象实例以及数组都在堆上分配

方法区

线程共享

用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

常量池就是在方法区中

内存溢出异常

StackOverflowError异常

如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。

倘若存在大量的变量,或者方法中的操作非常多,归结就是栈帧足够大,将会超出栈(虚拟机栈)允许栈帧的最大容量(抛出StackOverflowError异常)。我们可以通过参数- Xss 来改变栈的内存容量。

OutOfMemoryError异常

如果虚拟机的栈内存允许动态扩展,当扩展栈容量无法申请到足够的内存时,将抛出
OutOfMemoryError异常。

  • Java堆内存溢出: Java堆存放的是实例对象,如果实例对象足够多,会导致堆内存溢出,堆具有大小,倘若超出此大小必然导致堆内存溢出。有些虚拟机具有自动扩展功能(堆最小值-Xms参数和最大值-Xmx参数,倘若最小值和最大值一样,可避免堆自动扩展)

内存泄漏 和内存溢出

  • 内存泄漏:存在对象实例无法被垃圾回收机制回收。当对象实例被引用了,但引用该对象实例的对象没有被引用。

文章来源:智云一二三科技

文章标题:Java 虚拟机

文章地址:https://www.zhihuclub.com/182837.shtml

关于作者: 智云科技

热门文章

网站地图