首页 > 系统相关 >了解 Java 内存模型

了解 Java 内存模型

时间:2023-08-07 11:32:44浏览次数:31  
标签:Java Eden 对象 模型 GC 内存 S1


Java内存模型(Java Memory Model)是Java语言规范定义的一套规则,提供了一组规则和同步机制,以确保多线程程序在多线程环境下正确地处理内存访问的一致性和可见性问题。开发人员在编写多线程程序时,需要遵守Java内存模型的规则,并使用适当的同步机制来保证程序的正确性。

1、Java内存模型主要关注以下两个方面:

内存一致性(Memory Consistency):在多线程环境下,多个线程同时访问内存中的数据时,如何保证数据的一致性。

可见性(Visibility):在一个线程修改了共享变量的值后,其他线程如何能够立即看到该修改。

2、为了解决这些问题,Java内存模型提供了以下同步机制:

原子性(Atomicity):对于一些基本数据类型,如int、long等,Java内存模型提供了原子操作,保证这些操作在多线程环境下是原子性的,即不会被其他线程干扰。

互斥性(Mutual Exclusion):使用synchronized关键字或ReentrantLock等同步机制,将代码块或方法声明为互斥的,保证同一时间只有一个线程能够访问该代码块或方法,从而避免多个线程同时修改共享变量的问题。

可见性(Visibility):使用volatile关键字或synchronized关键字等同步机制,保证一个线程修改了共享变量的值后,其他线程能够立即看到该修改。

无序性(Memory Reordering):Java内存模型允许编译器和处理器对指令进行重排序,以提高执行效率。但是,这可能会导致多线程环境下的一些问题。因此,需要使用volatile关键字或synchronized关键字等同步机制来保证指令顺序执行。

1

Java 对象内存布局

了解 Java 内存模型_内存模型

一个 Java 对象在内存中包括对象头、实例数据和补齐填充3个部分:

了解 Java 内存模型_java_02

对象头包括以下3个部分:

Mark Word:包含一系列的标记位,比如对象的哈希码、分代年龄、锁标志等等。在 32 位系统占 4 字节,在 64 位系统中占 8 字节。

Class Pointer:用来指向对象对应的类元数据的内存地址。在 32 位系统占 4 字节,在 64 位系统中占 8 字节。

Length:如果是数组对象,还有一个保存数组长度的空间,占4个字节,数组对象特有的。

实例数据:包括对象的所有成员变量,其大小由各个成员变量的大小决定,比如:byte 和 boolean 是 1 个字节,short 和 char 是 2 个字节,int 和 float 是 4 个字节,long 和 double 是 8个字节,对于引用类型来说,在 32 位系统上占用 4 个字节, 在 64 位系统上占用 8 个字节。

对齐填充:所有 Java 对象占用的字节数必须是 8 的倍数,也就是说如果一个 Java 对象占用的空间不是 8 的倍数,为了保证对象的大小为 8 字节的整数倍,那么就需要补齐填充为 8 的倍数。

2

Java 内存模型介绍

了解 Java 内存模型_Java_03

JVM 内存模型分为非堆区(Metaspace)和堆区,堆区分为两大块:一块是 Old 区,一块是 Young 区,Old:Young=2:1;Young区分为两大块:一块是 Eden 区,一块是 Survivor区(S0+S1),S0 和 S1 一样大,也可以叫 ServivorFrom、 ServivorTo,Eden:S0:S1=8:1:1。

了解 Java 内存模型_Java_04

一般对象和数组的创建会在堆中分配内存空间,新创建的 Java 对象存放在 Eden 区。

Eden 区:新创建的 Java 对象存放在 Eden 区(如果新创建的对象占用内存很大,则直接分配到老年代 Old区),当 Eden 区内存不够的时候就会触发 MinorGC,对新生代 Young 区进行一次垃圾回收。每经历一次Minor GC(复制算法回收对象)就会让对象的年龄加 1,当对象年龄为 15 时就会把新生代的对象放入老年代中(年龄默认是 15 岁,可以通过参数 -XX:MaxTenuringThreshold 来设置)。

比如有对象 Object1,Object2,Object3 等在 Eden 区,但是 Eden区的内存空间是有限的,比如有 500M,假如已经使用了 500M 或者达到设定内存的临界值,这时候就需要对 Eden 区的内存空间进行清理,即垃圾收集(Garbage Collect),这样的 GC 我们称之为 Minor GC,Minor GC 指的就是对 Young 区的 GC。经过 GC 之后,有些对象就会被清理掉,有些对象可能还存活着,对于存活着的对象需要将其复制到 Survivor 区,然后再清空 Eden 区中的这些对象。

Survivor 区:Survivor 区分为两块 S0 和 S1,也可以叫做 ServivorFrom 和 ServivorTo,在同一个时间点上,S0 和 S1 只能有一个区有数据,另外一个是空的。

假如一开始只有 Eden 区和 S0 中有对象,S1 中是空的,此时进行一次 GC 操作, S0 区中的对象的年龄就会加 1,若 S0 区中对象年龄达到设置的年龄阈值,此时对象会被移动到 Old 区,如果 Eden 区和 S0 区没有达到年龄阈值的对象会被复制到 S1 区,此时 Eden 区和 S0 区已经被清空了(没有被 GC 的对象要么到了Old 区,要么到了 S1 区), 这时候 S0 和 S1角色互换,之前的 S0 变成了 S1,之前的 S1 变成了 S0,也就是说无论如何都要保证名为 S1 的 Survivor 区域是空的(用于保留经过一次 Minor GC 后的存活对象),Minor GC 会一直重复这样的过程,直到 S1 区被填满,然后会将所有对象复制到老年代中。

Old 区:一般 Old 区都是年龄比较大的对象,或者超过了设置的年龄阈值的对象,在 Old 区也会有 GC 的操作,Old 区的 GC 我们称作为 Major GC。

我们经常说的 3 种 GC 方式:

Minor GC:新生代

Major GC:老年代

Full GC:新生代 + 老年代(因为 Major GC 一般伴随着 Minor GC,两个一起就是 Full GC)。

3

使用 jvisualvm 查看内存使用情况

了解 Java 内存模型_Java_05

在 jdk 安装目录 bin 文件夹里找到 jvisualvm.exe,点击可以打开 Java VisualVM,或者在命令行打开(需要配置环境变量),如下:

了解 Java 内存模型_java_06

安装 Visual GC 插件

可以在 Java VisualVM  面板里,点击“工具 ---> 插件 ---> 可用插件”里找到 Visual GC 安装,或者添加自己下载的 Visual GC 插件,如下:

了解 Java 内存模型_java_07

插件 Visual GC 下载:https://visualvm.github.io/uc/8u131/updates.html

了解 Java 内存模型_开发语言_08

下载后的文件:com-sun-tools-visualvm-modules-visualgc.nbm 大小:43.4kb。

安装之后,重启 Java VisualVM,出现 Visual GC 页面,安装成功。

在 Visual GC 页面,我们可以清晰的看到具体的内存使用情况,同时也验证了 Java 内存模型就是分为非堆区(Metaspace)和堆区(Old+Young(Old+Eden+S0+S1)),如下:

了解 Java 内存模型_java_09

后面将为大家介绍垃圾回收算法。

标签:Java,Eden,对象,模型,GC,内存,S1
From: https://blog.51cto.com/javazyx/6991980

相关文章

  • javaee 创建泛型方法
    packagecom.test.generic;importjava.util.Collection;publicclassTestGenericClass{ //泛型方法?extendsE:泛型的限定 publicstatic<E>voidmove(Collection<E>from,Collection<?superE>to) { for(Ee:from) { to.add(e);......
  • 基于Java敬老院管理系统的设计与实现
     随着社会的快速发展,人们的工作节奏不断提高,大多数的家庭都面临着工作和家庭很难兼顾的问题,对于家里有生活无法自理的老人来说,更是有着极大地困扰。敬老院行业正式在这种背景下逐渐的发展起来,但是因为使用的手工管理方式,导致敬老院管理效率低下,无法解决养老院发展带来的巨大工作量......
  • 行业报告 | 大模型助力产业,持续推进人工智能科技创新
    原创|文BFT机器人随着AI应用深入千行百业,大模型在多个产业领域发挥着积极的作用。英伟达、META、微软等多家公司纷纷宣布AI相关行业的合作和并购机会,加速研发各垂类领域AI大模型,算力需求有望持续向上。英伟达:宣布5000万美元投资Recursion,加速开发生物和化学AI基础模型。Recursio......
  • 五种云计算服务模型IaaS、PaaS、SaaS、KaaS、FaaS
    云计算通常可以分为三种类型:基础设施即服务(InfrastructureasaService,IaaS)平台即服务(PlatformasaService,PaaS)软件即服务(SoftwareasaService,SaaS)其中,IaaS提供基本的计算、存储和网络基础设施,PaaS在此基础上提供了开发和部署应用程序的平台,而SaaS则提供了直接使用的应用......
  • DDD项目落地之充血模型实践
    背景:充血模型是DDD分层架构中实体设计的一种方案,可以使关注点聚焦于业务实现,可有效提升开发效率、提升可维护性;1、DDD项目落地整体调用关系调用关系图中的Entity为实体,从进入领域服务(Domin)时开始使用,直到最后返回。2、实体设计充血模型是实体设计的一种方法,简单来说,就是一种......
  • 比较 Java Enterprise Architecture 中的 MongoDB 和 Couchbase
    MongoDB和Couchbase是两种常用的NoSQL数据库,用于在Java实现的企业架构中存储和管理数据。以下是它们之间的主要差异、比较和权衡。在当今快速发展的企业架构领域,MongoDB和Couchbase已经成为NoSQL数据库中两个重要的竞争者。本文全面探讨了这两个强大解决方案之间的关键差异、比较和......
  • 基于java物业管理系统
    随着社会的快速发展,人们对物业的要求不断提高,大多数的物业都面临着工作量繁杂的问题,对于较大的物业来说来说,更是有着极大地困扰。物业管理系统正式在这种背景下逐渐的发展起来,但是因为使用的手工管理方式,导致管理效率低下,无法解决社会发展带来的巨大工作量。本文通过调研物业管理面......
  • java 从外部强制结束死循环代码
    publicclassThreadTimeoutExample{publicstaticvoidmain(String[]args){Threadthread=newThread(newMyRunnable());thread.start();//启动线程try{thread.join(3000);//等待线程执行,设置超时时间为3秒......
  • LLaMA大语言模型
    什么是LLaMALLaMA是由美国的MetaAI发布的大语言系列模型,全称是LargeLanguageModelMetaAI,论文:LLaMA:OpenandEfficientFoundationLanguageModels。Llama这个单词本身是指美洲大羊驼,所以社区也将这个系列的模型昵称为羊驼系模型。在这篇论文中,使用数万亿个(trillionsof)tok......
  • JAVA学习路线
    参考路线:初级阶段Java语言基础在Java语言基础部分,你将学习Java语言的基本语法、数据类型、变量和运算符等知识。这些内容可以使用任何Java集成开发环境(IDE)进行学习,如Eclipse、IntelliJIDEA或NetBeans。数据库基础数据库基础部分将介绍SQL语法、数据库设计和基本的CRUD操作。你可以......