当前位置: 首页 > news >正文

Java基础知识总结(二):JVM内存结构与变量生命周期

Java基础知识总结(二):JVM内存结构与变量生命周期

很多Java开发者刚开始学习时都会有这样的疑问:

  • 对象到底存在哪里?
  • new出来的对象什么时候被回收?
  • 局部变量和成员变量有什么区别?
  • static变量到底存放在哪里?

这些问题都与 JVM 内存结构密切相关。

本文将从 JVM 运行时数据区出发,深入理解 Java 程序运行过程中内存是如何分配和管理的。


目录

  • JVM内存结构概述
  • 程序计数器
  • Java虚拟机栈
  • 本地方法栈
  • 堆内存
  • 方法区
  • 对象创建过程
  • 成员变量与局部变量区别
  • static变量存储位置
  • 生命周期分析
  • 常见面试题
  • 总结

一、JVM内存结构概述

Java程序运行时,JVM会将内存划分为多个区域。

主要包括:

┌──────────────┐ │ 程序计数器 │ ├──────────────┤ │ Java虚拟机栈 │ ├──────────────┤ │ 本地方法栈 │ ├──────────────┤ │ 堆 │ ├──────────────┤ │ 方法区 │ └──────────────┘

通常面试中提到的JVM内存结构,指的就是这些运行时数据区。


二、程序计数器(Program Counter Register)

程序计数器是一块较小的内存空间。

作用:

记录当前线程正在执行的字节码指令地址。

简单理解:

程序执行到哪一行代码了 程序计数器负责记录

例如:

publicstaticvoidmain(String[]args){inta=10;intb=20;intc=a+b;System.out.println(c);}

JVM执行时:

执行第一句 记录位置 执行第二句 更新位置 执行第三句 更新位置

程序计数器就是一个“导航仪”。


为什么需要程序计数器?

Java支持:

  • 多线程
  • 线程切换

例如:

线程A执行一半 CPU切换到线程B 线程B执行完 再切换回线程A

程序计数器能够帮助线程恢复到之前执行的位置。


特点

程序计数器:

线程私有

每个线程都有自己的程序计数器。

也是 JVM 唯一不会发生 OutOfMemoryError 的区域。


三、Java虚拟机栈(Stack)

栈是面试中最常见的知识点之一。

作用:

保存方法运行时产生的数据。


方法调用过程

例如:

publicstaticvoidmain(String[]args){test();}publicstaticvoidtest(){intnum=10;}

执行过程:

main() 入栈 ↓ test() 入栈 ↓ test()执行结束 ↓ test()出栈 ↓ main()结束 ↓ main()出栈

图示:

┌───────┐ │ test │ ├───────┤ │ main │ └───────┘

栈中存放什么?

主要存放:

局部变量 方法参数 方法调用信息 返回地址

例如:

publicvoidtest(){inta=10;Stringname="Tom";}

变量:

a name

都存放在栈中。


栈的特点

先进后出(FILO)

Last In First Out

后进入的方法先执行完毕。


四、本地方法栈(Native Method Stack)

本地方法栈专门服务于:

native

修饰的方法。

例如:

publicnativevoidstart0();

JDK底层很多功能都依赖native方法实现。

例如:

  • 操作系统交互
  • 文件系统
  • 网络通信
  • 硬件访问

为什么需要本地方法?

Java本身无法直接操作:

CPU 内存 磁盘 网卡

因此需要借助:

C C++

编写的本地方法实现。


五、堆(Heap)

堆是 JVM 中最大的一块内存区域。

作用:

存储对象和数组。


对象创建过程

例如:

Studentstu=newStudent();

执行时:

第一步

栈中创建引用变量

stu

第二步

堆中创建对象

Student对象

第三步

引用指向对象

stu → Student对象

图示:

栈(Stack) stu │ ▼ 堆(Heap) Student对象

数组也存放在堆中

例如:

int[]nums={1,2,3};

图示:

栈 nums │ ▼ 堆 [1,2,3]

堆中的默认值

对象创建后会自动初始化。

例如:

classUser{intage;booleanflag;}

创建对象:

Useruser=newUser();

默认值:

age=0flag=false

为什么堆需要GC?

因为:

newUser();newUser();newUser();

会不断创建对象。

如果不回收:

内存耗尽

因此 JVM 提供:

Garbage Collection

垃圾回收机制。


六、方法区(Method Area)

方法区用于保存:

类信息 方法信息 常量 静态变量 运行时常量池

例如:

publicclassUser{privateStringname;publicvoidlogin(){}}

类加载后:

User类的信息 login方法的信息

都会进入方法区。


方法区的发展

JDK6

永久代(PermGen)

属于方法区实现。


JDK8

永久代被移除。

改为:

元空间(MetaSpace)

使用本地内存。


七、对象创建全过程

例如:

Useruser=newUser();

执行过程:

1. 类加载

如果User类未加载:

加载User.class

进入方法区。


2. 分配内存

在堆中创建对象。


3. 默认初始化

例如:

intage;

初始化为:

0

4. 调用构造方法

publicUser(){}

执行构造方法。


5. 返回对象地址

引用变量保存地址。

user → 对象

八、成员变量与局部变量区别

这是面试高频题。


定义位置不同

成员变量:

publicclassUser{intage;}

定义在类中、方法外。


局部变量:

publicvoidtest(){intage=18;}

定义在方法内部。


默认值不同

成员变量:

有默认值。

例如:

intage;

默认:

0

局部变量:

没有默认值。

必须先赋值再使用。

错误示例:

publicvoidtest(){intage;System.out.println(age);}

编译失败。


作用域不同

成员变量:

整个对象

都可以访问。


局部变量:

仅当前方法

有效。


存储位置不同

成员变量:

跟随对象存在。


局部变量:

跟随方法存在。


生命周期不同

成员变量:

对象创建 ↓ 对象销毁

局部变量:

方法开始 ↓ 方法结束

对比表

对比项成员变量局部变量
定义位置类中方法中
默认值
存储位置
生命周期对象生命周期方法生命周期
作用域整个类当前方法

九、static变量存储位置

很多初学者认为:

static变量在堆中

实际上需要区分JDK版本。


JDK6

永久代(方法区)

JDK8+

元空间保存类信息 静态变量实际存储在堆中

因此现在更准确的说法:

静态变量属于类 生命周期与类一致 对象共享同一份静态变量

示例:

publicclassUser{publicstaticintcount=0;}

无论创建多少对象:

newUser();newUser();newUser();

都共享:

count

十、常见面试题

面试题1

对象存放在哪里?

答案:

堆(Heap)

面试题2

局部变量存放在哪里?

答案:

Java虚拟机栈

面试题3

数组存放在哪里?

答案:


面试题4

方法调用为什么要入栈?

答案:

保存方法运行状态 记录局部变量 记录返回地址

面试题5

成员变量和局部变量有什么区别?

答案:

定义位置不同 默认值不同 作用域不同 生命周期不同 存储位置不同

面试题6

为什么Java需要垃圾回收?

答案:

对象不断创建 如果不回收 最终导致内存耗尽

总结

本文介绍了 JVM 运行时数据区的重要组成部分:

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

同时分析了:

  • 对象创建过程
  • 成员变量与局部变量区别
  • static变量存储位置
  • 生命周期差异

掌握这些知识后,你将能够更好地理解:

  • 对象为什么会被回收
  • 内存溢出的原因
  • JVM性能调优基础
  • Java面试中的内存相关问题
http://www.zskr.cn/news/1489132.html

相关文章:

  • 零基础学 ArkUI24:手把手教你开发一个简易浏览器 App
  • 一篇读懂薛定谔定律:从微观宇宙到人生启示
  • 2026推荐:广州双极真空泵维修服务公司专业精修与高效服务之选 - 企业推荐官【官方】
  • PrivateGPT 1.0:构建企业级私有AI应用的开源API层
  • LLM —— Prompt提示词工程
  • GoLiveChat:Golang独立部署海外英文在线客服系统全解析
  • 2026年GEO优化服务商可靠性综合评估报告:数据驱动下的专业选型指南 - GEO优化
  • 【网络实验】用华为eNSP配置路由器DHCP服务,实现PC自动获取IP地址
  • 如何用10分钟语音数据训练专属AI音色:Retrieval-based-Voice-Conversion-WebUI完整指南
  • 终极指南:Ucupaint让Blender纹理图层管理变得如此简单![特殊字符]
  • 打破监控协议壁垒:go2rtc如何让传统摄像头在现代浏览器中焕发新生
  • RTSPtoWeb:实时视频流转换的技术革新与架构革命
  • 别再折腾了!Parallels Desktop 17 给CentOS 7虚拟机配静态IP,看这篇就够了(附网络诊断命令)
  • 5分钟玩转Zotero-GPT:让你的文献管理拥有AI超能力
  • 2026年 东莞WMS智能仓储系统推荐榜:五金/电子/塑胶/灯饰行业深度测评与优选指南 - 企业推荐官【官方】
  • 2026 惠州防水补漏服务商口碑测评榜单|全屋渗漏维修机构优选指南 - 宅安选房屋修缮
  • 考研复习 Day 48 | 密码学--第八章 数字签名与身份认证(上)
  • Kinetis MCU Flashloader配置与实战:从源码编译到固件更新全解析
  • nltknltk:自然语言处理的经典工具包
  • 遗憾藏于暗恋,温柔了整个青春
  • 轻量化AI赋能:重塑日常英语学习的高效路径
  • 2026年轻触开关厂家推荐榜单:带灯/贴片/防水/按键/硅胶/四脚轻触开关优质品牌精选推荐! - 品牌发掘
  • PLC四层电梯设计(设计源文件+万字报告+讲解)(支持资料、图片参考_降重降ai)
  • 避坑指南:处理Apple Pay订阅续期和状态码21006的那些事儿
  • 青少年工程官网导航揭秘:专业音频唱片录制系统 APC–2 亮相!
  • 2026年厦门垃圾车/环卫垃圾车厂家推荐榜:压缩式、餐厨、自装卸等市政物业保洁垃圾车品质实力解析 - 品牌发掘
  • 保姆级教程:用YOLOv8和OpenCV PnP复现Yolo-6D的核心思想(附Python代码)
  • 家庭投资组合方案(2026/6/7版)
  • 2026年二甲基二甲氧基硅烷/片碱/硝酸铈/氯化镧等化学原料厂家推荐榜单:热门化工品优选与行业口碑之选 - 品牌发掘
  • 用过才敢说!2026年最值得信赖的专业AI论文写作工具