JVM内存结构的组成、各部分功能作用

一、程序计数器

JVM内存结构的组成、各部分功能作用

作用:是记住下一条jvm指令的执行地址

特点

是线程私有的

不会存在內存溢出

二、虚拟机栈

JVM内存结构的组成、各部分功能作用

每个线程运行时所需要的内存,称为虚拟机栈
每个栈由多个栈帧(Frame) 组成,对应着每次方法调用时所占用的内存
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

问题辨析

1.垃圾回收是否涉及栈内存? 不会,垃圾回收是回收堆内存中的无用对象,栈内存中是一次次的方法调用产生的栈帧內存,而在每次方法调用完成之后,都会被弹出栈,自动被回收。

2.栈内存分配越大越好吗? 不是。栈內存可以在运行代码时,通过虚拟机参数进行指定(-Xss1m),物理內存的大小一定,栈內存越大,划分的线程数越小

3.方法内的局部变量是否线程安全?

■ 如果方法内局部变量没有逃离方法的作用访问,它是线程安全的
■ 如果是局部变量引用了对象,并逃离方法的作用方法,需要考虑线程安全

栈內存溢出(java.lang.StackOverflowError)

栈帧过多导致栈內存溢出(方法的递归调用,没有设置一个正确的结束条件)

栈帧过大导致栈內存溢出(一般不会出现)

线程运行诊断

案例 1: cpu 占用过多
定位
■用top定位哪个进程对cpu的占用过高
■psH -eo pid,id,%cpu | grep进程id (用ps命令进- 步定位是哪个线程引|起的cpu占用过高)
■jstack 进程id
■可以根据线程id找到有问题的线程,进一步定位到问题代码的源码行号

案例 2:程序运行很长时间没有结果

程序内部可能发生死锁

三、本地方法栈

作用: java虚拟机在调用 本地方法(C/C++ 编写的本地方法)时,需要给本地方法提供一些內存空间

四、堆

定义 :通过new关键字,创建对象都会使用堆內存

特点:它是线程共享的,堆中对象都要考虑线程安全的问题,有垃圾回收机制

堆内存溢出(java.lang.OutOfMemoryError):堆中对象过多,且都是有用对象,导致堆内存溢出 , 程序运行过程中也可以设置最大堆空间(-Xmx8m)

堆內存诊断

1.jps工具
查看当前系统中有哪些java进程
2. jmap工具
查看堆内存占用情况 jmap -heap 进程id
3. jconsole工具
图形界面的,多功能的监测工具,可以连续监测

4.jvisualvm工具

图形界面的,功能更加齐全,可定位到具体的对象的属性

五、方法区

官方定义:Java虚拟机中有一个被所有jvm线程共享的方法区。方法区有点类似于传统编程语言中的编译代码块或者操作系统层面的代码段。它存储着每个类的构造信息,譬如运行时的常量池,字段,方法数据,以及方法和构造方法的代码,包括一些在类和实例初始化和接口初始化时候使用的特殊方法。方法区在jvm启动时候被创建。虽然方法区在逻辑层面上是堆的一部分,但是就简单实现来说既不会被回收也不会被压缩。这个规范并不强制指定方法区存放的位置也不会对编译过的代码有管理策略的限制。方法区可能有一个固定的大小或者也可以通过计算大小去扩展也可以在不需要的时候被压缩。方法区的内存也不需要是连续的。Jvm虚拟机实现可以提供给编程人员或者用户初始化方法区的大小,同时在方法区可变大小的情况下,控制这个方法区的最大值和最小值。

程序启动时可手动设置方法区大小(jdk1.8 -XX:MaxMetaspaceSize=8m 、jdk1.6 -XX:MaxPermSize=8m)

1.6版本

JVM内存结构的组成、各部分功能作用

1.8版本

JVM内存结构的组成、各部分功能作用

内存溢出:当类加载器加载大数量的类到內存中,可能会出现內存溢出(前提:设置了方法区的最大元空间大小),1.8以前是导致永久代的內存溢出,1.8以后是导致元空间的內存溢出

常量池:就是一张表,存在于字节码文件里,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息

运行时常量池:常量池是* .class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

StringTable的特性:

常量池中的字符串仅是符号,第一次用到时才变为对象
利用串池的机制,来避免重复创建字符串对象
字符串 变量拼接的原理是StringBuilder (1.8)
字符串 常量拼接的原理是编译期优化

JVM内存结构的组成、各部分功能作用

可以使用intern方法,主动将串池中还没有的字符串对象放入串池,并把池串中的对象返回

1.8 将这个字符串尝试放入串池,如果有则不放入,如果没有则放入串池,会把串池中的对象返回

1.6 将这个字符串尝试放入串池,如果有则不放入,如果没有则会把此对象复制一份放入串池,会把串池中的对象返回

StringTable性能调优:

调整-XX:StringTableSize=桶个数
考虑将字符串对象是否入池

六、直接內存

定义:不是java虚拟机的內存,而是操作系统的內存

常见于NIO操作时,用于数据缓冲区
分配回收成本较高,但读写性能高
不受JVM内存回收管理

分配和回收原则:

使用了Unsafe对象完成直接内存的分配回收,并且回收需要主动调用freeMemory方法
ByteBuffer的实现类内部,使用了Cleaner (虚引用) 来监测ByteBuffer对象,一 旦ByteBuffer对象被垃
圾回收,那么就会由ReferenceHandler线程通过Cleaner 的clean方法调用freeMemory来释放直接内存

Original: https://www.cnblogs.com/yclblogs/p/15914057.html
Author: 阿龙同学
Title: JVM内存结构的组成、各部分功能作用

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/588927/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 枚举.Java学习

    今天复习一下Java里面的 枚举 。 枚举简介 使用enum关键字开发一个枚举类的时候,这个类会默认继承Enum系统类。而且是一个final类。 当多个枚举存在时候。需要逗号分隔,…

    Java 2023年6月9日
    060
  • 某意大利小哥,竟靠一个缓存中间件直接封神?

    大家好,我是二哥呀!关注我有一段时间的小伙伴都知道了,我最近的业余时间都花在了编程喵🐱这个实战项目上,其中要用到 Redis,于是我就想,索性出一期 Redis 的入门教程吧——主…

    Java 2023年6月9日
    068
  • Java学习-动手动脑4

    异常处理 public class SystemExitAndFinally { public static void main(String[] args) { try { Sy…

    Java 2023年6月9日
    081
  • Spring:读入properties文件程序示例

    文章目录 + [项目目录结构](#-1) + [properties文件](#properties-4) + [xml文件](#xml-11) + [java文件](#java-3…

    Java 2023年5月30日
    073
  • Redis入门讲解(介绍、安装、常用命令)

    Redis入门讲解(介绍、安装、常用命令) Redis是非关系型数据库 关系型数据库 关系型数据库是采用了关系模型来组织数据的数据库,以行和列的形式存储数据,由二维表及其之间的关系…

    Java 2023年6月15日
    080
  • 有效的写作的特点

    1.提早表述中心思想 ① 你根本不知道自己在思考什么;一两句话概况你要表达的内容; ② 如果有必要,修改几次,确保那就是你想表述的。 ③ 写作时要回头看看,避免偏离方向(思考也是如…

    Java 2023年6月5日
    097
  • 今年我经历了裸辞,自由职业,再就业

    大家好,我是3y 这是一篇我对2021年的总结文章,记得上一次写这种类型文章的我还是在2019年。没错,2020年我并没有写年终总结。 今天突发奇想,想记录下自己2021年做了些什…

    Java 2023年6月9日
    077
  • SQL的一种写法,匹配就更新,否则就是插入

    语法:(using里面可以是查询语句,也可以是dao层传入来的对象,集合) 例子 (mybatis写法,dao层传入来的集合对象) 解析: Original: https://ww…

    Java 2023年6月9日
    080
  • SpringBoot集成Thymeleaf发送Html邮件报错

    由于业务需求需要使用Thymeleaf作为模板发送Html邮件,开发调试过程中发生以下错误 开始以为是Classpath下不存在这个文件或者解析时候传入参数不对等等原因,排查了半天…

    Java 2023年6月13日
    085
  • Java学习-第一部分-第一阶段-第六节:面向对象编程(基础)

    面向对象编程(基础) 笔记目录:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 类与对象 ●使用现有技术解决 张老太养了两…

    Java 2023年6月16日
    097
  • Spring Cloud 任务简介

    一、概述 Spring Cloud Task 的目标是为 Spring Boot 应用程序提供创建短期微服务的功能。 在 Spring Cloud Task 中,我们可以灵活地动态…

    Java 2023年5月30日
    060
  • Redis 安装与使用

    NoSQL 1. 定义 NoSQL(Not Only SQL)即不仅仅是 SQL,泛指非关系型的数据库 2. 为什么使用 NoSQL? 传统关系数据库在应付动态网站、特别是超大规模…

    Java 2023年6月8日
    085
  • 安装pystaller

    安装命令 -i指定下载地址,&#x6B6…

    Java 2023年6月8日
    078
  • Docker安装Mysql

    安装 权威的都在官方: https://registry.hub.docker.com/ 先看看官方文档1、搜索mysql镜像2、找到对应镜像3、根据版本复制对应版本镜像拉取命令4…

    Java 2023年6月5日
    0100
  • 每日一问:讲讲 Java 虚拟机的垃圾回收

    昨天我们用比较精简的文字讲了 Java 虚拟机结构,没看过的可以直接从这里查看: 今天我们必须来看看 Java 虚拟机的垃圾回收算法是怎样的。不过在开始之前,我们一定得确定哪些是活…

    Java 2023年5月29日
    081
  • 继承

    public class 子类名 extends 父类名 { } ​ 注意事项:Java 不支持多继承 可以多层继承 (一个类不可以直接有多个父类,可以有父类的父类) ​ 让类3与…

    Java 2023年6月8日
    082
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球