JVM第二篇(JVM内存结构)

JVM的内存结构主要分为:

  1. 程序计数器
  2. 虚拟机栈
  3. 本地方法栈
  4. 方法区

下面先开始学习程序计数器部分

程序计数器(Program Counter Register)

JVM 指令,java程序的源文件,被编译为.class字节码文件,在字节码文件中,java的源文件被编译为一条条的JVM指令,JVM指令在所有操作系统下是通用的。
左侧是JVM指令,右侧为对应的Java源代码
请添加图片描述
JVM指令的执行流程,JVM 指令不能直接被CPU执行,JVM指令经过解释器,变成机器码,机器码再由CPU 进行执行。

程序计数器的作用就是记住当前JVM指令的下一条指令的内存地址。
在计算机中,用一个寄存器,来实现程序计数器的功能。

程序计数器的特点:

  1. 程序计数器是线程所私有的,每一个线程都有对应的程序计数器
  2. 程序计数器是唯一一个不会存在内存溢出的区

虚拟机栈

在数据结构中,栈的特点就是,先进后出,后进先出。

每个线程运行时所需要的内存,称为虚拟机栈,在线程运行的时候,存放线程运行时的数据。
每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存,每个栈帧存放着方法中的变量,参数,返回地址等数据信息。

每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法。

常见问题:
垃圾回收是否涉及栈内存?
不涉及,因为栈的内存是由栈帧组成,栈帧就是一次次的方法调用,在方法执行结束之后,栈帧会自动的释放内存。

栈内存分配越大越好吗?
不是越大越好, 因为物理内存是有限的,栈内存越大,则可以并行的线程数就越少,栈内存越大,则每个线程所能进行的递归调用的层数就越深,栈内存大并不能带来性能上的提升。

方法内的局部变量是否线程安全?
如果方法内局部变量没有逃离方法的作用访问,它是线程安全的
如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全

栈内存的溢出

  1. 由于栈中的栈帧过多,而导致内存溢出,例如在递归调用中, 未正确的设置结束条件,造成栈溢出(常见)
  2. 由于栈中的栈帧过大,从而导致内存溢出 ( 不太常见 )

本地方法栈

本地方法概念:指不是用 java代码写的方法,由于java 的语言特性,java 不能对操作系统的底层进行操作,所以需要间接调用 C/C++ 编写的底层方法,与操作系统底层进行操作。

本地方法栈就是在运行本地方法时为本地方法创建的栈内存结构。

在 java 的Object类中,大量的调用了本地方法。
加上 native关键字 后的函数的实现不是用java写的

 public native int hashCode();
 public final native void notify();
 public final native void notifyAll();
 public final native void wait(long timeout) throws InterruptedException;


通过new 关键字声明的对象都会被放入堆内存中。
堆是线程所共享的内存区域,堆中的对象都需要考虑线程安全问题。
堆中有垃圾回收机制,在堆中不再被引用的对象,内存将会被回收。

堆内存溢出:在堆内存中存放的对象过多,超过了堆中的内存大小,将会使得堆内存溢出。

方法区

方法区与堆类似,方法区是所有线程共享的内存区域。
方法区类似于传统语言的编译代码存储区,或类似于操作系统进程中的“文本”段。它存储每个类的结构,例如运行时常量池、字段和方法数据,以及方法和构造函数的代码,包括在类和实例初始化和接口初始化中使用的特殊方法,方法区是在虚拟机启动时创建的。

在不同厂商,不同版本的JDK中,对方法区的实现也是不同的。
在JDK1.6中,方法区是由一个被称为永久代所实现的。
永久代是在堆中存储的,由JVM所管理的内存空间。
永久代中包含Class的信息,ClassLoader的信息,还有字符串常量池等。
请添加图片描述
在JDK1.8中,方法区是由一个被称为元空间所实现的。
元空间已经不占用堆的内存了,元空间不是由JVM所管理的内存空间,直接由操作系统来管理。
在元空间中,同样的包含Class的信息,ClassLoader的信息,以及常量池的信息等。
不过在元空间中,已经不进行存储字符串常量池了,字符串常量池存放在堆内存中。
请添加图片描述

方法区的内存溢出:
在方法区中存放着类的信息,如果加载的类过多,则有可能造成方法区内存的溢出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值