【JVM-1】JVM内存结构

一、定义

Java Virtual Machine --java的运行环境(java二进制字节码的运行环境)

JVM提供的功能:

  • 一次编写,到处运行
  • 自动内存管理,垃圾回收功能
  • 数组下标越界检查
  • 多态

比较(包含关系)
JVM
JRE:JVM+基础类库 Java RuntimeEnvironment
JDK:JVM+基础类库+编译工具
开发JavaSE: JDK+IDE
开发JavaEE:JDK+应用服务器+IDE

jvm是一套规范eg :HotSpot,Oracle JDK

二、JVM内存结构

java源代码-> 二进制字节码(jvm指令)->解释器->解释为机器码->CPU

1. 程序计数器

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

  • 是线程私有的(每个线程有自己的程序计数器)
  • 不会存在内存溢出

2. 虚拟机栈

定义

栈-线程运行需要的内存空间
栈帧组成
一个栈帧对应一次方法的调用 每个方法运行时需要的内存
包含的信息有:参数,局部变量,返回地址等
当方法执行完,就把这个栈帧弹出

总结

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

问题

  1. 垃圾回收是否涉及栈内存? no 不需要垃圾回收。GC回收堆内存中的对象
  2. 划分更多栈内存? 不会提升效率
  3. 方法内的局部变量是否线程安全? (线程中变量有无共享?)
    每个线程各有一个栈,线程中的每个方法各有一个栈帧,调用时放到该线程的栈里。 共享的变量才要考虑线程安全问题

栈内存溢出

  • 递归没有合理的结束条件(栈帧过多导致栈溢出)
  • 栈帧过大导致栈溢出

线程运行诊断

  1. CPU占用过多
  2. 死锁

3. 本地方法栈 Native Method Stacks

不是java代码编写的接口。其他语言的本地方法接口需要使用本地方法栈
native

作用:给本地方法的运行提供内存空间

4. 堆

通过new关键字,创建对象都会使用堆内存

特点

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

堆内存溢出

OutOfMemoryError: Java heap space
堆内存诊断

  1. jps工具 查看进程 jps
  2. jmap 查看堆内存占用情况 jmap -heap 进程id
  3. jconsole 图形界面 jdk自带

在这里插入图片描述

案例:垃圾回收后,内存占用仍然很高

jvisualvm
在这里插入图片描述
点击[堆dump] 可以截取快照
在这里插入图片描述

5. 方法区

线程内共享的区域,存与类相关的信息
方法区在虚拟机启动时被创建,逻辑上是堆的组成部分

方法区也会导致内存溢出。
1.8以前导致永久代内存溢出
1.8以后会导致元空间内存溢出

元空间内存溢出
场景: Spring MyBatis

运行时常量池
二进制字节码组成:类基本信息,常量池,类方法定义-包含了虚拟机指令
.class javap -v Helloworld.class

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值