首页 > 系统相关 >Day12 jvm 内存模型JMM

Day12 jvm 内存模型JMM

时间:2023-12-04 17:59:31浏览次数:33  
标签:Java jvm 对象 实例 线程 内存 Day12 JMM java

1. jvm 内存模型 JMM

原帖链接

  • JMM控制 Java 线程之间的通信,决定一个线程对共享变量的写入何时对另一个线程可见。
  • 每条线程在自己的工作内存中对共享变量(副本)进行操作,JMM再负责把这些操作同步到主内存中
  • JVM1.8 用Meta space(元空间)(在JVM外的本地内存中)取代了方法区(Method Area)(在JVM堆中)

jvm内存分配

1.1 Java heap

Java 堆是垃圾收集器管理的主要区域,因此也被称作GC堆(Garbage Collected Heap)

1.1.2 字符串常量池
  • 字符串常量池原本存放于方法区,jdk7开始放置于堆中。
  • 字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table
1.1.3 对象实例
  • 类初始化生成的对象
  • 基本数据类型的数组也是对象实例
1.1.4 线程分配缓冲区
  • 增加线程分配缓冲区是为了提升对象分配时的效率

1.2 本地内存(元空间实现的方法区)

元空间并不在虚拟机中,而是使用本地内存

  • JDK8开始用元空间实现原来java heap中的方法区

  • -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC(garbage collection)会对改值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。

  • -XX:MaxMetaspaceSize,最大空间,默认是没有限制的

1.2.1类元信息(Klass)(有点类定义的意思)
  • 类元信息在类编译期间放入方法区,里面放置了类的基本信息,包括类的版本、字段、方法、接口以及常量池表(Constant Pool Table)
  • 常量池表(Constant Pool Table)存储了类在编译期间生成的字面量、符号引用,这些信息在类加载完后会被解析到运行时常量池中
1.2.2运行时常量池(Runtime Constant Pool)
  • 运行时常量池主要存放在类加载后被解析的字面量与符号引用

1.3 本地方法栈

本地方法栈则是为执行本地方法(Native Method)服务的。简单地讲,一个Native Method就是一个java调用非java代码的接口。一个Native Method是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制。

2.TLAB机制

堆是全局共享的,因此在同一时间,可能有多个线程在堆上申请空间,在并发场景中,就会存在两个线程先后把对象引用指向了同一个内存区域,所以对象的内存分配过程需要一个同步机制,但是无论是使用哪种同步方案(实际上虚拟机使用的可能CAS),都会影响内存的分配效率。所以HotSpot虚拟机的提供了一个解决方案:TLAB分配,即Thread Local Allocation Buffer。(TLAB只是的一个优化方案,不代表所有的虚拟机都有这个特性)

  • 每个线程在Java堆中预先分配一小块内存,然后再给对象分配内存的时候,直接在自己这块”私有”内存中分配,当这部分区域用完之后,再分配新的”私有”内存。

因为有了TLAB技术,堆内存是线程共享的这个命题是不准确的

3. 对象在JVM中的内存布局

推荐看以下链接

Java对象实例化过程以及对象实例内存分布

Java对象实例内存分布

在new一个对象时,jvm创建instanceOopDesc,来表示这个对象,存放在堆区,其引用存放在栈区;平时说的Java Object Layout就是instanceOopDesc,它用来表示对象的实例信息;instanceOopDesc对应java中的对象实例。

instanceOopDesc包含三部分:
image

    1. 对象头,也叫Mark Word,主要存储对象运行时记录信息,如hashcode, GC分代年龄,锁状态标志,线程ID,时间戳等;
  • 对象头还包括 class pointer指向方法区的 Klass

    • 每个实例对象对klass的引用都是同一个
    1. 实例数据,是对象真正存储的有效信息,包括程序代码中定义的各种类型的字段(包括从父类继承下来的和本身拥有的字段)
    1. 填充。无实际意义, 。 HotSpot 要求对象起始地址都是 8 字节的整数倍,所以要对齐
      image

image

image

标签:Java,jvm,对象,实例,线程,内存,Day12,JMM,java
From: https://www.cnblogs.com/wendao101/p/17875544.html

相关文章

  • JVM-垃圾回收器
    G1收集器G1收集器的内存结构完全区别去CMS,弱化了CMS原有的分代模型(分代可以是不连续的空间),将堆内存划分成一个个Region(1MB~32MB,默认2048个分区),这么做的目的是在进行收集时不必在全堆范围内进行。它主要特点在于达到可控的停顿时间,用户可以指定收集操作在多长时间内完成,即G1提......
  • JVM-常量池
    概要:1.Java基本类型的包装类的大部分都实现了常量池技术,即Byte、Short、Integer、Long、Character、Boolean;2.且数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。3.两种浮点数类型的包装类Float、Double并没有实现常量池技术。实例:Inte......
  • JVM-垃圾回收
    虚拟机栈:描述的是方法执行时的内存模型,是线程私有的,生命周期与线程相同,每个方法被执行的同时会创建栈桢(下文会看到),主要保存执行方法时的局部变量表、操作数栈、动态连接和方法返回地址等信息,方法执行时入栈,方法执行完出栈,出栈就相当于清空了数据,入栈出栈的时机很明确,所以这......
  • Java环境变量配置及报错java --version Error: could not open `D:\APP\Develop\JA
    C:\Users\Administrator>java--versionError:couldnotopen`D:\APP\Develop\JAVA\jre\lib\amd64\jvm.cfg'Java环境变量的配置控制面板→系统→高级系统设置→环境变量在下方系统变量中新建在下方系统变量中找到Path,双击打开,新建两个%JAVA_HOME%\bin%JAVA_HOME%\jre\b......
  • JVM内存模型
    JVM内存模型堆:新生代老年代常量池字符串常量池运行时常量池虚拟机栈:栈帧方法区:元空间本地方法栈:程序计数器:java内存结构(JMM内存模型)主内存:工作内存:java线程高速缓存操作变量时的规则:Java内存模型规定了所有的变量都存储在主内存线程的工作内存中保存了被该......
  • 查看JVM默认参数
    java-XX:+PrintFlagsFinal-version[Globalflags]uintxAdaptiveSizeDecrementScaleFactor=4{product}uintxAdaptiveSizeMajorGCDecayTimeScale=10{product}u......
  • Day12 变量、常量、作用域
    变量变量:可以变化的量java是一种强类型语言,每个变量都必须声明其类型。java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。//数据类型变量名=值;可以使用逗号隔开来声明多个同类型变量(不建议这么做会很乱)注意事项:每个变量都有类型,类型可以是基本类......
  • JVM学习记录六(JVM调优实战案例)
    这几期的文章都通过学习黑马课程里老师的内容总结出来的,想看视频的伙伴可以上B站搜索《黑马程序员》一、内存溢出内存溢出的位置有三个,如图所示:思路:1.获取堆内存快照2.VisualVM分析dump文件3.通过查看对内信息的情况,定位内存溢出的问题4.找到代码,找到问题代码进行修复二、CPU飚高......
  • day12 购物车系统实战
    注册函数:defregisiter():withopen(r"F:\pylearn\day12\购物车系统\账号密码.txt","r",encoding="utf8")asfr:user_dict=dict()data=fr.read()foriinrange(len(data.split())):user_dict[data.......
  • JVM 内存分析工具 MAT 的深度讲解与实践
     1.MAT工具简介MAT(全名:MemoryAnalyzerTool),是一款快速便捷且功能强大丰富的JVM堆内存离线分析工具。其通过展现JVM异常时所记录的运行时堆转储快照(Heapdump)状态(正常运行时也可以做堆转储分析),帮助定位内存泄漏问题或优化大内存消耗逻辑。1.1MAT使用场景及主要解决问......