【JVM 内存结构丨堆】

  • 定义
  • 内存分配
    • 特点:
      • 分代结构
      • 对象分配过程
      • Full GC /Major GC 触发条件
      • 引用方式
      • 堆参数
      • 堆内存实例

在这里插入图片描述

主页传送门:📀 传送

定义


  JVM(Java Virtual Machine)堆是Java应用程序运行时内存管理的重要组成部分之一。堆内存用于存储Java对象实例,这些对象在运行时被动态分配和管理。

  一个 JVM 实例只存在一个堆内存,堆内存的大小是可调节的。它取决于应用程序的需求和JVM的配置。

内存分配


  1. 新生代(Young Generation):新生代是JVM堆的一小部分,通常占整个堆的1/10到1/4。它主要用于存储新创建的对象。新生代又可以分为Eden区和两个Survivor区(S0和S1)。大多数对象都在Eden区中创建,当Eden区满时,会触发Minor GC,将还存活的对象移动到Survivor区。
  2. 老年代(Old Generation):老年代是JVM堆的另一部分,用于存储长时间存活的对象。当Eden区或Survivor区中的对象经过一定次数的GC后仍然存活,或者大对象直接在老年代中创建,就会触发Major GC。
  3. 永久代(PermGen)或元空间(Metaspace):jdk7之前有永久代,DK 8之后这个部分被元空间替代。永久代用于存储JVM字节码和类的元数据。元空间则是将这部分内存抽象出来,让JVM在堆外进行分配,以减轻堆内存的压力。
  4. 方法区(Method Area):方法区是用来存储已被加载的类信息、常量、静态变量以及即时编译器编译后的代码等数据。方法区的内存回收目标主要针对常量池的回收和对类型的卸载。

图解如下:
在这里插入图片描述

特点:


  • 线程共享,整个 Java 虚拟机只有一个堆,所有的线程都访问同一个堆。(程序计数器、Java 虚拟机栈、本地方法栈都是一个线程对应一个。)
  • 在虚拟机启动时创建。(当运行Java应用程序时,JVM会启动,并在内存中分配一块区域来作为堆内存。这个过程发生在JVM启动的早期阶段,通常在执行java命令启动Java程序的时候。且一旦堆内存被创建,它就会在整个Java应用程序的生命周期中存在,直到应用程序结束或JVM关闭。)
  • 是垃圾回收的主要场所。(JVM的垃圾回收器定期扫描堆中的对象,找到不再被引用的对象,并释放它们的内存。)

分代结构

  • 堆可分为新生代(Eden 区:From Survior,To Survivor)、老年代。

  • 新生代用于存储新创建的对象,而老年代用于存储存活时间较长的对象。

  • Java 虚拟机规范规定,堆可以处于物理上不连续的内存空间中,但在逻辑上它应该被视为连续的。

  • 关于 Survivor s0,s1 区: 复制之后有交换,谁空谁是 to。

  • 老年代比新生代生命周期长。

  • 新生代与老年代空间默认比例 1:2:JVM 调参数,XX:NewRatio=2,表示新生代占 1,老年代占 2,新生代占整个堆的 1/3。

  • Eden 空间和另外两个 Survivor 空间缺省所占的比例是:8:1:1。

  • 几乎所有的 Java 对象都是在 Eden 区被 new 出来的,Eden 放不了的大对象,就直接进入老年代了。

对象分配过程


  • new 的对象先放在 Eden 区,大小有限制
  • 如果创建新对象时,Eden 空间填满了,就会触发 Minor GC,将 Eden 不再被其他对象引用的对象进行销毁,再加载新的对象放到 Eden 区,特别注意的是 Survivor 区满了是不会触发 Minor GC 的,而是 Eden 空间填满了,Minor GC 才顺便清理 Survivor 区
  • 将 Eden 中剩余的对象移到 Survivor0 区
  • 再次触发垃圾回收,此时上次 Survivor 下来的,放在 Survivor0 区的,如果没有回收,就会放到 Survivor1 区
  • 再次经历垃圾回收,又会将幸存者重新放回 Survivor0 区,依次类推
  • 默认是 15 次的循环,超过 15 次,则会将幸存者区幸存下来的转去老年区 jvm 参数设置次数 : -XX:MaxTenuringThreshold=N 进行设置
  • 频繁在新生区收集,很少在养老区收集,几乎不在永久区/元空间搜集

Full GC /Major GC 触发条件


  • 显示调用System.gc(),老年代的空间不够,方法区的空间不够等都会触发 Full GC,同时对新生代和老年代回收,FUll GC 的 STW 的时间最长,应该要避免
  • 在出现 Major GC 之前,会先触发 Minor GC,如果老年代的空间还是不够就会触发 Major GC,STW 的时间长于 Minor GC

引用方式


四种引用方式

  • 强引用:创建一个对象并把这个对象赋给一个引用变量,普通 new 出来对象的变量引用都是强引用,有引用变量指向时永远不会被垃圾回收,jvm 即使抛出 OOM,可以将引用赋值为 null,那么它所指向的对象就会被垃圾回收。
  • 软引用:如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。
  • 弱引用:非必需对象,当 JVM 进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。
  • 虚引用:虚引用并不会决定对象的生命周期,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

堆参数


参数说明示例
-Xms设置初始堆大小。-Xms256m表示初始堆大小为256MB。默认值通常是较小的值,例如32MB。
-Xmx设置最大堆大小。-Xmx1024m表示最大堆大小为1GB。根据应用程序的需求,可以调整这个值。一般此值建议与-Xmx相同,避免每次垃圾回收完成后JVM重新分配内存
-Xmn设置新生代的大小。(新生代是堆的一部分,用于存储新创建的对象。)-Xmn256m表示新生代大小为256MB。
-XX:MaxPermSize(在Java 7之前)指定永久代(Permanent Generation)的最大大小。永久代用于存储类的元数据信息等。-XX:MaxPermSize=128m表示永久代最大为128MB。
-XX:MaxMetaspaceSize(Java 8及以后)指定元空间(Metaspace)的最大大小。元空间取代了永久代,用于存储类的元数据信息。-XX:MaxMetaspaceSize=256m表示元空间最大为256MB。
-XX:PermSize(在Java 7之前)指定永久代的初始大小。-XX:PermSize=64m表示永久代的初始大小为64MB。
-XX:MetaspaceSize(Java 8及以后)指定元空间的初始大小。-XX:MetaspaceSize=128m表示元空间的初始大小为128MB。
-XX:NewRatio=设置新生代和老年代的大小比例。-XX:NewRatio=2表示新生代大小为老年代大小的1/3。
-XX:SurvivorRatio=设置新生代中Eden区和Survivor区的大小比例。-XX:SurvivorRatio=8表示Eden区大小是Survivor区大小的8倍。
-XX:+UseSerialGC使用串行垃圾回收器适用于单线程应用程序。
-XX:+UseParallelGC使用并行垃圾回收器。适用于多核处理器的应用程序。
-XX:+UseConcMarkSweepGC使用CMS(Concurrent Mark-Sweep)垃圾回收器。适用于需要降低垃圾回收停顿时间的应用程序。

堆内存实例

public class HeapMemoryExample {public static void main(String[] args) {// 创建一个数组对象并分配到堆内存中int[] numbers = new int[1000];// 堆内存中的对象可以动态修改for (int i = 0; i < numbers.length; i++) {numbers[i] = i * 2;}// 创建一个字符串对象并分配到堆内存中String greeting = "Hello, World!";// 堆内存中的对象可以通过引用来访问System.out.println(greeting);// 创建自定义对象并分配到堆内存中Person person1 = new Person("Alice", 25);Person person2 = new Person("Bob", 30);// 堆内存中的对象可以相互引用person1.setFriend(person2);person2.setFriend(person1);}
}class Person {private String name;private int age;private Person friend;public Person(String name, int age) {this.name = name;this.age = age;}public void setFriend(Person friend) {this.friend = friend;}
}

  上面的示例中创建了一个整数数组、一个字符串和自定义的Person对象,并将它们分配到堆内存中。堆内存中的对象可以通过引用来访问,可以进行动态修改和相互引用。这些对象的内存管理由JVM的垃圾回收器负责,不需要手动释放内存。

在这里插入图片描述

  如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏  🙌一起讨论你的支持就是我✍️创作的动力!					  💞💞💞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/110164.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue学习之vue cli创建项目

安装 node.js https://nodejs.org/en 安装 vue cli npm install -g @vue/cli --registry=https://registry.npm.taobao.org创建项目 执行创建命令,回车vue create vue-cli-learning选择 “Manually select features”,回车 “空格” 关闭 Linter / Formatter 选项,回车

android注解之APT和javapoet

前言 前面我们已经讲过注解的基本知识&#xff0c;对于注解还不太了解的&#xff0c;可以去看一下之前的文章&#xff0c; android 注解详解_袁震的博客-CSDN博客。 之前我们在讲注解的时候&#xff0c;提到过APT和JavaPoet&#xff0c;那么什么是APT和JavaPoet呢&#xff1…

【ChatGPT原理与实战】4个维度讲透ChatGPT技术原理,揭开ChatGPT神秘技术黑盒!

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

Cesium 地球网格构造

Cesium 地球网格构造 Cesium原理篇&#xff1a;3最长的一帧之地形(2&#xff1a;高度图) HeightmapTessellator 用于从高程图像创建网格。提供了一个函数 computeVertices&#xff0c;可以根据高程图像创建顶点数组。 该函数的参数包括高程图像、高度数据的结构、网格宽高、…

网络安全深入学习第四课——热门框架漏洞(RCE— Log4j2远程代码执行)

文章目录 一、log4j2二、背景三、影响版本四、漏洞原理五、LDAP和JNDI是什么六、漏洞手工复现1、利用DNSlog来测试漏洞是否存在2、加载恶意文件Exploit.java&#xff0c;将其编译成class文件3、开启web服务4、在恶意文件Exploit.class所在的目录开启LDAP服务5、监听反弹shell的…

SEO优化排名的技巧与注意点(百度SEO排名的五大注意点)

关键词排名是指在搜索引擎中&#xff0c;用户搜索相关关键词时&#xff0c;网站出现的顺序。SEO优化是提高网站排名的一种方法。优化关键词排名的目的是提高网站流量和知名度。但是要注意遵循百度SEO排名的规则。 下面介绍一下百度SEO排名的五大注意点和优化关键词的六种方式。…

如何实现一个简单的Promise/A+规范的Promise库?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Promise/A规范的Promise⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚…

去除pdf/word的水印艺术字

对于pdf中的水印如果无法去除水印&#xff0c;则先另存为word&#xff0c;然后再按下面办法处理即可&#xff1a; 查看宏&#xff0c;创建&#xff1a;删除艺术字 添加内容&#xff1a; Sub 删除艺术字()Dim sh As ShapeFor Each sh In ActiveDocument.ShapesIf sh.Type msoT…

第二节:利用VBA代码交换三个单元格的值

【分享成果&#xff0c;随喜正能量】经常在做一件事时&#xff0c;一开始动力很足&#xff0c;可时间久了&#xff0c;就会出现意志力消耗殆尽。流水不腐&#xff0c;户枢不蠹。做一件对自己好的小事&#xff0c;养一个好习惯&#xff0c;慢慢坚持&#xff0c;持续去做&#xf…

HAProxy终结TLS双向认证代理EMQX集群

文章目录 1. 背景介绍2. 系统架构3. 证书签发3.1 创建根证书3.2 创建中间证书3.3 创建设备证书3.4 创建服务端证书 4. HAProxy开启双向认证5. 验证6. 总结 1. 背景介绍 MQTT协议已经成为当前物联网领域的关键技术之一&#xff0c;当前市面上主流的实现MQTT协议的产品主要有 EMQ…

【微服务】六. Nacos配置管理

6.1 Nacos实现配置管理 配置更改热更新 在nacos左侧新建配置管理 Data ID&#xff1a;就是配置文件名称 一般命名规则&#xff1a;服务名称-环境名称.yaml 配置内容填写&#xff1a;需要热更新需求的配置 配置文件的id&#xff1a;[服务名称]-[profile].[后缀名] 分组&#…

CSS:实现文字溢出显示省略号且悬浮显示tooltip完整信息

组件&#xff1a; element ui中的tooltip组件 思路&#xff1a;通过ref获取宽度进行判断&#xff0c;当子级宽度大于对应标签/父级宽度显示tooltip组件 <div class"bechmark-wrap"><ul ref"bechmarkUl"><liv-for"(item,index) in comp…