jvm内存的模型

本文介绍了JVM内存模型的关键组成部分,包括堆、栈、程序计数器、本地方法栈等,探讨了它们的功能、线程可见性和空间大小的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

jvm的是整个java程序运行的根本,那程序如何在jvm中进行存放,如何处理的,都将是一个java工程师在提高自己的路上的必经之路。现在就简单的谈一谈jvm的内存模型。
当一个程序进入时往往是以进程的形式来运行调用的,那进程是如何看待内存模型的。
堆:是由堆和永久区组成的。
栈:是由java栈,本地方法栈区,程序计数器构成的。

jvm内存中包含整个系统内存的堆栈两大块,所以详细来看一下堆栈的包含的内存块及应用。
在具体介绍他们的功能必须要了解的几点

  1. 进程是有一个或者多个线程组成的
  2. 堆是线程共享的而栈是线程私有的依旧是每一个线程都会生成单独的一个栈内存 在了解以上基础特性以后,对于下面的解释就好理解了。我们先从线程私有的栈来解释。

jvm栈中有一个是程序计数器,程序计数器它所占的内存很小,当前线程执行的字节码行号指示器(就是告诉
jvm你这个线程执行到哪一行),因为是线程私有的所以每一个线程独立存储的互不影响的。又因为占的内存很少,基本上不会在这里出现oom。

java栈:当每个方法在执行的同时会创建一个栈帧用于存储局部变量,操作数栈,动态链接,方法出入口等信息。方法的执行就是对应栈帧在jvm中的入栈和出栈的过程。栈里面存放着各种基本类型和对象的引用。

本地方法栈:本地方法栈保存的是Native方法的信息,当一个jvm线程调用Native方法后,jvm不在为其在jvm中创建栈帧,而是直接简单的动态链接并直接调用。

堆:Java堆是Javaer需要重点 关注的一块区域,因为涉及到 内存的分配(new关键字,反射 等)与回收(回收算法,收集器 等);主要是存放对象的地方。

方法区:也叫永久区,用于存 储已经被虚拟机加载的类信息 ,常量(“zdy”,”123”等),静态变 量(static变量)等数据。在jvm创建一个对象的时候,顺序是这样的编译器首先会在类加载器中找是否有这个class的缓存,然后把class的一些相关信息放入方法区中,当要new一个实例化的对象时就去方法区中找到相关类的信息进行实例化放入java堆中。jdk1.8取消了方法区,jdk1.7将常量移入了java堆中。

运行时常量池:运行时常量池 是方法区的一部分,用于存放编译期生成的各种字面量 (“zdy”,”123”等)和符号引用。多数为字符串常量。

直接内存:不是虚拟机运行 时数据区的一部分,也不是 java虚拟机规范中定义的内存区域(一个进程必须有的功能因为要加载jvm的代码);

  1. 如果使用了NIO,这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作;
  2. 这块内存不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认 与堆内存最大值一样),所以也会出现OOM异常;

堆和栈道区别

功能
  1. 栈:以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char等)以及对象的引用变量,其内存分配在栈上,变量出了作用域就会自动释放;
  2. 堆:而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中;
线程独享还是共享
  1. 栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
  2. 堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。
空间大小
  1. 栈的内存要远远小于堆内存,栈的深度是有限制的,如果递归没有及时跳出,很可能发生StackOverFlowError问题。栈的默认值是1M。
  2. 你可以通过-Xss选项设置栈内存的大小。-Xms选项可以设置堆的开始时的大小,-Xmx选项可以设置堆的最大值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值