JVM内存模型的简单了解

    了解JVM的运作对于Java程序员来说是一个知根知底的过程,可以帮助程序员写出高效的代码,同时对自己代码的运转有个了解,本文我们简单地介绍下JVM的内存模型。

    首先的,我们说说程序计数器,程序计数器的作用其实类似于传统处理器中的PC,是正在执行的字节码的行号指示器,通过改变自身的值,来控制需要选取哪一条字节码指令,从而做到分支、跳转、循环、异常处理等基础操作。为了保证每一次线程在获取CPU的时候程序计数器都能回到原来的位置,所以每一个线程都有一个独立的线程计数器,所以该内存空间为“线程私有”的。

    再就是Java虚拟机栈,它是Java方法处理的内存模型,每一个Java方法被调用的时候都会创建一个栈帧,栈帧中存储着局部变量表、操作数栈、动态链接、方法出口等内容。其中,局部变量表中存储着可预知的基础数据类型、对象引用、返回地址(指向一条字节码指令的地址),而一次方法的执行到返回,就意味着一次入栈和出栈,很显然,这部分的内存也是“线程私有”的。

    本地方法栈,大体上和Java栈相同,但是是服务于本地方法(Native)的。

    以上三种内存空间都是“线程私有”的,以下我们来讲述一些“线程公有”的内存模型,也就是意味着他们随着虚拟机的启动而创建,随着虚拟机的关闭而消亡。

    Java堆,几乎所有的对象实例和数组都是在该区域创建的,是JVM管理的最大的一块区域,也是GC活动的核心场所。

    方法区,当JVM使用类装载器装载一个类的时候,JVM会先找到指定的字节码文件,再读入该字节码文件,最后将其信息加在导方法区内存中,最后返回一个class实例。很显然,该内存主要用于存放类的信息,如类名、类修饰符等,其中方法区中有一片区域,叫做运行时常量池。运行时常量池用于存放字段、方法信息、静态变量。

    上诉五种都是为JVM所管理的内存区域,我们再介绍一种比较特殊的内存区域,直接内存,他是并不是JVM内存模型的划分范围,他的作用是什么呢?

    在JDK1.4之后,Java引入了NIO,一种基于通道和缓冲区的IO方式,使用native函数库直接分配堆外内存,如此就无需在Java堆上新建对象作为中间区域调用IO了。直接内存的读写效率是高于堆内存的,直接内存的申请耗费更高的性能。

### JVM内存模型详细介绍 JVMJava Virtual Machine)内存模型主要分为五个部分:堆(Heap)、方法区(Method Area)、虚拟机栈(Java Stack)、本地方法栈(Native Method Stack)和程序计数器(Program Counter Register)。以下是各部分的具体介绍: #### 堆(Heap) 堆是JVM中最大的一块内存区域,主要用于存储对象实例及数组值。所有的线程都共享这一块内存空间。通过`new`关键字创建的对象都会被分配在堆上[^4]。 可以通过命令行参数 `-Xms` 和 `-Xmx` 来设置堆的初始大小和最大大小。默认情况下,当剩余堆内存低于一定比例时,JVM会自动扩展堆的空间至最大限制;而当剩余堆内存超过设定的比例时,JVM可能会缩小堆的空间。 #### 方法区(Method Area) 方法区是非堆的一部分,也被称为永久代(Permanent Generation),尽管现代JDK版本已经将其替换为元空间(Metaspace)。它用于存储已被虚拟机加载的类信息、常量池、静态变量以及即时编译后的代码等数据[^1]。 需要注意的是,方法区内存不足可能导致 `OutOfMemoryError` 错误发生。 #### 虚拟机栈(Java Stack) 每个线程都有自己的虚拟机栈,它是线程私有的。每当一个新线程被创建时,就会为其分配一个新的虚拟机栈。每次调用一个方法时,会在对应的虚拟机栈中压入一个栈帧(Frame),用来保存局部变量表、操作数栈、动态链接、方法出口等信息[^3]。 如果线程请求的栈深度超过了允许的最大深度,则抛出 `StackOverflowError`;如果无法为新的线程分配足够的栈空间,则抛出 `OutOfMemoryError`。 #### 本地方法栈(Native Method Stack) 与虚拟机栈类似,但是本地方法栈服务于JNI(即 Native Interface)方法。它的功能主要是支持本地方法执行,每条线程也有自己独立的一份本地方法栈副本[^5]。 #### 程序计数器(Program Counter Register) 这是一个较小的内存区域,用于指示当前线程所执行的字节码指令的位置。如果是解释执行的Java方法,那么这个计数器就指向方法区中的某一条指令;但如果是在执行本地方法的话,此时计数器的值将是未定义的状态。因为程序计数器只记录下一条要执行的指令地址,并不涉及复杂的数据结构维护工作,所以不会出现内存溢出的情况[^5]。 综上所述,理解并合理配置这些不同的内存区域有助于提高应用程序性能,减少潜在错误的发生几率。 ```bash java -Xms1024m -Xmx1024m -Xmn512m -Xss5m MyApplication ``` 以上是一个简单的例子展示如何利用命令行选项调整JVM堆和其他相关参数。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值