Java 8 的内存结构
虚拟机内存与本地内存的区别
Java虚拟机在执行的时候会把管理的内存分配成不同的区域,这些区域被称为虚拟机内存,同时,对于虚拟机没有直接管理的物理内存,也有一定的利用,这些被利用却不在虚拟机内存数据区的内存,我们称它为本地内存,这两种内存有一定的区别:
JVM内存
本地内存
(1)程序计数器(Program Counter Register)
程序计数器就是当前线程所执行的字节码的行号指示器,通过改变计数器的值,来选取下一行指令,通过他来实现跳转、循环、恢复线程等功能
- 在任何时刻,一个处理器内核只能运行一个线程,多线程是通过线程轮流切换,分配时间来完成的,这就需要有一个标志来记住每个线程执行到了哪里,这里便需要到了程序计数器。
- 所以,程序计数器是线程私有的,每个线程都已自己的程序计数器。
(2)虚拟机栈(JVM Stacks)
虚拟机栈是线程私有的,随线程生灭。
每个方法被执行的时候,都会在虚拟机栈中同步创建一个栈帧(stack frame)。
每个栈帧的包含如下的内容
-
局部变量表
- 局部变量表中存储着方法里的java基本数据类型(byte/boolean/char/int/long/double/float/short)以及对象的引用(注:这里的基本数据类型指的是方法内的局部变量)
-
操作数栈
-
动态连接
-
方法返回地址
方法被执行时入栈,执行完后出栈。
- 如果线程请求的栈深度大于虚拟机所规定的栈深度,则会抛出StackOverFlowError即栈溢出
- 如果虚拟机的栈容量可以动态扩展,那么当虚拟机栈申请不到内存时会抛出OutOfMemoryError即OOM内存溢出
(3)本地方法栈(Native Method Stacks)
本地方法栈与虚拟机栈的作用是相似的,都会抛出OutOfMemoryError和StackOverFlowError,都是线程私有的,主要的区别在于:
- 虚拟机栈执行的是java方法
- 本地方法栈执行的是native方法
(4)Java堆(Java Heap)
Java堆(Java Heap)
java堆是JVM内存中最大的一块,由所有线程共享,是由垃圾收集器管理的内存区域,主要存放对象实例,当然由于java虚拟机的发展,堆中也多了许多东西,现在主要有:
java堆既可以是固定大小的,也可以是可扩展的(通过参数-Xmx和-Xms设定),如果堆无法扩展或者无法分配内存时也会报OOM。
(5)方法区(Method Area)
直接内存
直接内存位于本地内存,不属于JVM内存,但是也会在物理内存耗尽的时候报OOM。
Native方法
由于java是一门高级语言,离硬件底层比较远,有时候无法操作底层的资源,于是,java添加了native关键字,被native关键字修饰的方法可以用其他语言重写,这样,我们就可以写一个本地方法,然后用C语言重写,这样来操作底层资源。当然,使用了native方法会导致系统的可移植性不高,这是需要注意的。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战