栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JVM-1】JVM内存结构

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JVM-1】JVM内存结构

文章目录

一、定义二、JVM内存结构

1. 程序计数器2. 虚拟机栈

定义栈内存溢出线程运行诊断 3. 本地方法栈 Native Method Stacks4. 堆

堆内存溢出 5. 方法区

一、定义

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. 虚拟机栈 定义

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

总结

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

问题

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

递归没有合理的结束条件(栈帧过多导致栈溢出)栈帧过大导致栈溢出 线程运行诊断

    CPU占用过多死锁
3. 本地方法栈 Native Method Stacks

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

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

4. 堆

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

特点:

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

OutOfMemoryError: Java heap space
堆内存诊断:

    jps工具 查看进程 jpsjmap 查看堆内存占用情况 jmap -heap 进程idjconsole 图形界面 jdk自带

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

jvisualvm

点击[堆dump] 可以截取快照

5. 方法区

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

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

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

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

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/777608.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号