目录
前言
内存结构
程序计数器
虚拟机栈
本地方法栈
堆内存
方法区
内部组成
前言
- Java的JVM解决的问题是跨操作系统问题。程序员只需要专注于代码的编写,这些代码能够在不同的操作系统Mac,Linux和Windows运行的前提是JVM。
- JVM还提供了垃圾回收机制,这是一个围城,外面的人想进来,里面的人想出去。
内存结构
JVM的内存结构主要分为5部分,程序计数器,虚拟机栈,本地方法栈,堆和方法区。
- 其中虚拟机栈、程序计数器和本地方法栈是线程安全的即线程私有。
- 方法区和堆是线程不安全区域,也是变量或者引用类型存放的地方,也是垃圾回收主要面对的区域。
如下图所示,我们可以看到JVM的全貌
程序计数器
- 作用,是记住下一条jvm指令的执行地址
- 特点
- 是线程私有的
- 不会存在内存溢出
当线程发生上下文切换时候,这时候,程序还想顺序执行,程序计数器就发挥了重大作用。
虚拟机栈
特点
- 每个线程运行时所需要的内存,称为虚拟机栈
- 每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存
- 每个线程当前时刻只能有一个活动栈帧,对应着当前正在执行的那个方法
- -Xss 为jvm启动的每个线程分配的内存大小,默认JDK1.4中是256K,JDK1.5+中是1M
- 从其特点可以看出,虚拟机栈是线程私有的。因为每个线程都有一个虚拟机栈。每个虚拟机栈也会消耗一定内存。因此如果线程数过多会发生内存溢出问题。
- 每个方法对应一个栈帧,当我们递归调用写成无线调用时,就会发生栈溢出问题。
- 每个栈帧对应每个方法,每个方法中又存在局部变量,这些局部变量是否线程安全?
- 当局部变量的作用域仅在这个方法中,那么它是线程安全的。
- 如果局部变量引用了对象,并逃离了方法的作用范围,那么它是线程不安全的
本地方法栈
本地方法栈和虚拟机栈发挥的作用是非常相似的,
- 它们之间的区别不过在于虚拟机栈为虚拟机执行执行Java方法;
- 本地方法栈为虚拟机执行的是Native方法服务。
堆内存
特点
- 通过 new 关键字,创建对象都会使用堆内存
- 它是线程共享的,堆中对象都需要考虑线程安全的问题
- 有垃圾回收机制
- 通过Xms和-Xms控制堆的大小
- -Xms:为jvm启动时分配的内存
- Xmx:为jvm运行过程中分配的最大内存,比如-Xms500m,表示jvm进程最多只能够占用500M内存
堆内存诊断
1. jps 工具
- 查看当前系统中有哪些 java 进程
2. jmap 工具
- 查看堆内存占用情况 jmap - heap 进程id
3. jconsole 工具
- 图形界面的,多功能的监测工具,可以连续监测
方法区
内部组成
以1.8为例,方法区是JVM内存的一个概念,它具体使用元空间实现的。
运行时常量池
- 常量池,就是一张表是Class文件中一部分,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
- 常量池是 *.class 文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址
了解了JVM的内存结构可以关注一下对象是如何创建的
JVM—对象的创建_兜兜转转m的博客-CSDN博客