JVM内存结构

这篇具有很好参考价值的文章主要介绍了JVM内存结构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JVM内存结构,jvm,javaSe基础,jvm

类加载:类源代码经编译器编译为二进制字节码,通过类加载器加载到JVM

JVM内存:类存放方法区,实例对象存放中,方法调用时用到虚拟机栈、程序计数器、本地方法栈

执行引擎:解释器逐行解释执行方法代码,热点代码由JIT做编译、优化后的执行,GC负责回收堆中不再被引动的对象,当JAVA代码无法实现某些功能,需要使用底层操作系统功能,则需要调用本地(native)方法接口使用操作系统的功能方法

问题:代码是如何被翻译执行?

ANS:java源代码(.java文件)编译为二进制字节码(.class文件),按照JVM规范可知类文件结构(包含魔数、版本、常量池、访问标识与继承信息、成员变量信息、方法信息),可将二进制字节码翻译为JVM指令(这里可借助Oracle的javap工具反编译 class 文件),JVM跨平台的基础便依赖JVM指令,字节码指令最终由解释器逐行解释为机器码交由CPU执行.

1 程序计数器

定义 特点
用来记住下一条jvm指令的执行地址,供解释器循环读取
(物理上使用CPU中寄存器快速读取)
①是线程私有的
②不会存在内存溢出(规定)

2 虚拟机栈

JVM内存结构,jvm,javaSe基础,jvm

定义 垃圾回收 内存溢出 程序报错 线程安全 执行参数
栈为方法的内存占用(参数、局部变量、返回地址占用),
虚拟机栈就由多个栈帧组成,
虚拟机栈对应线程,栈帧对应方法,从栈的数据结构来理解,
调用线程内方法会压栈,方法执行完毕会弹栈,
栈顶则为活动栈帧(栈内唯一),对应着当前正在执行的方法
不涉及垃圾回收因为方法结束会弹栈
存在内存溢出,栈帧过大或过多都可能溢出,因此需要合理分配内存 java.lang.StackOverflowError
栈内存溢出
原因分析:
①方法递归调用
②类之间循环引用
①方法是否用到非局部变量
②局部变量是否逃离方法作用范围
-Xss1024k
栈内存大小

2.1 线程诊断运行(jstack命令)

案例一:

假设问题为cpu占用过高

定位

①用top定位哪个进程对cpu的占用过高

②ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)

​ H 输出进程信息

​ -eo pid,tid,%cpu 过滤出进程号,线程号,cpu占用率

③jstack 进程id

④可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号

​ 第②步中的tid十进制换为十六进制,对应的就是nid号

案例二:

程序运行很长时间没有结果

定位

通过jstack 可以看到问题为deadlock

3 本地方法栈

java调用本地native方法和操作系统打交道时,为其方法提供的内存

4 堆

定义 垃圾回收 内存溢出 程序报错 线程安全
new 关键字,创建对象都会使用堆内存 有垃圾回收机制 对象创建过多可能OOM java.lang.OutOfMemoryError:Java heap space
堆内存溢出
线程共享的,堆中对象都需要考虑线程安全的问题

4.1 堆内存划分(分代GC)

JVM内存结构,jvm,javaSe基础,jvm

  • 对象首先分配在伊甸园区域

  • 新生代空间不足时,触发 minor gc,伊甸园和 from 存活的对象使用 copy 复制到 to 中,存活的

  • 对象年龄加 1并且交换 from to

  • minor gc 会引发 stop the world,暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行

  • 当对象寿命超过阈值时,会晋升至老年代,最大寿命是15(4bit)

  • 当老年代空间不足,会先尝试触发 minor gc,如果之后空间仍不足,那么触发 full gc,STW的时间更长

4.2 相关VM参数

含义 参数
堆初始大小 -Xms
堆最大大小 -Xmx 或 -XX:MaxHeapSize=size
新生代大小 -Xmn 或 (-XX:NewSize=size + -XX:MaxNewSize=size )
幸存区比例(动态) -XX:InitialSurvivorRatio=ratio 和 -XX:+UseAdaptiveSizePolicy
幸存区比例 -XX:SurvivorRatio=ratio
晋升阈值 -XX:MaxTenuringThreshold=threshold
晋升详情 -XX:+PrintTenuringDistribution
GC详情 -XX:+PrintGCDetails -verbose:gc
FullGC 前 MinorGC -XX:+ScavengeBeforeFullGC

4.3堆内存诊断工具

命令 作用
jps 查看当前系统中有哪些 java 进程
jmap -heap 进程号 查看堆内存占用情况(堆配置参数+各区域占用情况)
jconsole 图形界面的,多功能的监测工具,可以连续监测
jvirsualvm 可视化虚拟机, 堆转储dump, 可查看对象个数和大小

5 方法区

定义 垃圾回收 内存溢出 程序报错 线程安全 执行参数 工具
存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等 大量的类被加载导致元空间(1.6永久代)内存溢出 java.lang.OutOfMemoryError:Metaspace
元空间内存溢出
java.lang.OutOfMemoryError: PermGen space
永久代内存溢出
线程共享的 -XX:MaxMetaspaceSize=8m
-XX:MaxPermSize=8m
javap -v 类
反编译查看方法区信息

JVM内存结构,jvm,javaSe基础,jvm

JVM内存结构,jvm,javaSe基础,jvm

版本 存储位置
1.6 (1.8以前) 占用堆内存,由永久代实现
1.8 提出元空间概念,由本地内存管理,不归JVM内存管理,但是串池StringTable存放堆中

5.1 常量池(constant pool)

参考:常量池和StringTable

6 直接内存

定义 特点 内存溢出
由原来的数据经由系统内存缓冲区(java不可访问)拷贝到JVM内存缓冲区供JVM访问的方式
,改为,数据直接写入direct memory直接内存缓冲区供JVM读取的方式
常见于 NIO 操作时,用于数据缓冲区
分配回收成本较高,但读写性能高
不受 JVM 内存回收管理
java.lang.OutOfMemoryError:Direct buffer memory
系统内存不足导致直接内存溢出

JVM内存结构,jvm,javaSe基础,jvm

6.1 分配和回收原理

  • 使用了 Unsafe 对象完成直接内存的分配回收,并且回收需要主动调用 freeMemory 方法

  • ByteBuffer 的实现类内部,使用了 Cleaner (虚引用)来监测 ByteBuffer 对象,一旦ByteBuffer 对象被垃圾回收,那么就会由 ReferenceHandler 线程通过 Cleaner 的 clean 方法调用 freeMemory 来释放直接内存文章来源地址https://www.toymoban.com/news/detail-823725.html

到了这里,关于JVM内存结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM内存结构介绍

    一、java代码编译执行过程   1.源码编译:通过Java源码编译器将Java代码编译成JVM字节码(.class文件)   2.类加载:通过ClassLoader及其子类来完成JVM的类加载   3.类执行:字节码被装入内存,进入JVM虚拟机,被解释器解释执行         注:Java平台由Java虚拟机和Java应用程序接口

    2024年02月16日
    浏览(37)
  • JVM 内存结构

    Java 虚拟机的内存空间分为 5 个部分: 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在

    2024年02月11日
    浏览(36)
  • 【JVM 内存结构丨栈】

    主页传送门:📀 传送   栈是用于执行线程的内存区域,它包括局部变量和操作数栈。 Java 虚拟机栈会为每一个即将运行的 Java 方法创建一块叫做“栈帧”的区域,用于存放该方法运行过程中的一些信息,如: 局部变量表 操作数栈 动态链接 方法出口信息 … 图示如下 :

    2024年02月11日
    浏览(31)
  • JVM内存结构

    类加载:类源代码经编译器编译为二进制字节码,通过 类加载器 加载到JVM JVM内存:类存放 方法区 ,实例对象存放 堆 中,方法调用时用到 虚拟机栈、程序计数器、本地方法栈 执行引擎: 解释器 逐行解释执行方法代码,热点代码由 JIT 做编译、优化后的执行, GC 负责回收堆中不再被引

    2024年01月25日
    浏览(31)
  • 【JVM】内存结构

    Java 虚拟机的内存空间分为 5 个部分: 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在

    2024年01月23日
    浏览(34)
  • JVM-内存结构

    1、定义 程序计数器(Program Counter)是JVM中的一块较小的内存区域,它是一个指向当前线程正在执行的字节码指令的指针。 程序计数器使用的是寄存器 ,特点-快。 程序计数器作用是 记住下一条jvm执行的执行地址。 特点: 线程私有的 不会存在内存溢出-jvm规定了 2、作用 程

    2024年02月15日
    浏览(46)
  • 复习一下JVM内存结构

    程序计数器内存很小,可以看作是 当前线程 所执行字节码的 行号指示器 。 有了它,程序就能被正确的执行。 因为有 线程切换 的存在,则每个线程必须有各自独立的程序计数器,即 线程私有 的内存。 这里再解释一下什么是 线程切换 ,线程切换指的是: 单处理器在执行

    2024年02月20日
    浏览(109)
  • JVM学习笔记(二)内存结构

    目录   一、JVM内存结构 1. 虚拟机栈(JVM Stacks) 1)定义 2)栈内存溢出 3) 线程运行诊断 案例1:CPU占用过高 案例2:程序运行很长时间没有结果​编辑 2. 本地方法栈(Native Method Stacks) 3.  堆(Heap) 1)定义 2)特点 3)堆内存溢出 4)堆内存诊断 5)案例:垃圾回收后,内存

    2024年02月16日
    浏览(35)
  • 【JVM 内存结构 | 程序计数器】

    主页传送门:📀 传送 Java 虚拟机的内存空间由 堆、栈、方法区、程序计数器和本地方法栈五部分组成。   JVM(Java Virtual Machine)内存结构包括以下几个部分: 堆区(Heap):堆区是最大的一块内存区域,由所有线程共享。所有的对象实例以及数组都在这块内存中分配。 方

    2024年02月11日
    浏览(44)
  • JVM基础篇-直接内存

    什么是直接内存? 直接内存( 堆外内存 ) 指的是 Java 应用程序通过直接方式从操作系统中申请的内存,这块内存不属于jvm 传统方式读取文件 首先会从用户态切换到内核态,调用操作系统函数从磁盘读取文件,读取一部分到操作系统缓冲区中 然后从内核态切换到用户态,从系统

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包