IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> JVM——内存结构 -> 正文阅读

[Java知识库]JVM——内存结构

内存结构

  1. 程序计数器
  2. 虚拟机栈
  3. 本地方法栈
  4. 方法区

1 程序计数器

定义
Program Counter Register 程序计数器(寄存器)的作用,是记住下一条jvm指令的执行地址。
特点
是线程私有的。
不会存在内存溢出。

2 虚拟机栈

虚拟机栈是线程私有。

定义
Java Virtual Machine Stacks (Java 虚拟机栈)每个线程运行时所需要的内存,称为虚拟机栈。

每个栈由多个栈帧(Frame)组成,对应着每次方法调用时所占用的内存。
栈帧是指每个方法运行时所需要的内存(参数,局部变量,返回地址等)。
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法。

-Xss去改变栈空间大小。

问题辨析

  1. 垃圾回收是否涉及栈内存? 不涉及
  2. 栈内存分配越大越好吗? 并不是,因为总内存是固定的,如果栈内存分配大了,就会导致线程数变少。
  3. 方法内的局部变量是否线程安全?
    如果方法内局部变量没有逃离方法的作用访问,它是线程安全的。
    如果是局部变量引用了对象,并逃离方法的作用范围,需要考虑线程安全。

栈内存溢出
栈帧过多导致栈内存溢出。比如我们用递归调用时,没有设置结束语句,就会导致java.stackOverflowError 。

栈帧过大导致栈内存溢出。(这种情况很少见)

线程运行诊断
案例1:cpu占用过高
解决办法:
用top定位哪个进程对cpu的占用过高:
ps H -eo pid,tid,%cpu | grep 进程id (用ps命令进一步定位是哪个线程引起的cpu占用过高)。
jstack 进程id:
可以根据线程id 找到有问题的线程,进一步定位到问题代码的源码行号。
案例2:程序运行很长时间没有结果
可能是代码之间发生了死锁(deadlock)。

3. 本地方法栈(Native Method Stacks)

java在调用本地方法时所处的内存空间(例如Object的一些方法)。
本地方法栈是线程私有。

4. 堆(Heap)

定义
通过 new 关键字,创建对象都会使用堆内存。
特点
它是线程共享的,所以堆中对象都需要考虑线程安全的问题。
有垃圾回收机制。

堆内存溢出(OutOfMemoryError:java heap space)
堆内存溢出一般情况下是新创建的对象不断的去调用原来的对象,导致无法进行垃圾回收。
-Xmx 去改变堆空间大小。
关于堆中的新生代和老年代会在以后的文章中专门讲解。
堆内存诊断

在Java下点击Terminal就可以使用jps等工具。

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

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

因为代码实际情况,然后我们去进行查看到底是什么原因这时候用到了我们的jvisualvm工具中的堆Dump,就可以去进行查看,到底是哪个问题导致我们垃圾回收后,内存占用仍然很高。

5. 方法区(OutOfMemoryError)

定义
方法区存储信息主要:类信息,类加载器(加载类的二进制字节码),域信息,方法信息,常量,静态变量,即时编译器编译后的代码缓存。
特点
1.方法区在jvm启动的时候被创建。
2.方法区也是线程共享的

组成
1.6和1.8版本的变化如图,在这幅图中应该更能清楚方法区的内存结构

在这里插入图片描述方法区内存溢出
1.8 以前会导致永久代内存溢出

演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace
-XX:MaxMetaspaceSize=8m

1.8 之后会导致元空间内存溢出

演示元空间内存溢出 java.lang.OutOfMemoryError: Metaspace
-XX:MaxMetaspaceSize=8m

场景
spring
mybatis

在使用这两个框架时,可能需要调用大量的类,所以很容易导致永久代的溢出,但是在1.8之后元空间使用的是系统内存,就不会容易导致内存溢出了。而且垃圾回收也有区别,在以后的文章中会讲解到。
常量池
我们的编程语言最后都会转变为计算机能读懂的二进制字节码,而二进制字节码中主要包括类基本信息,常量池,类方法定义。
常量池,就是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息。
常量池是 *.class 文件中的。
作用
一个java源文件的类,接口,编译后产生一个字节码文件。而java中字节码需要数据支持,通常这种数据会很大以至于不能直接存储在字节码里,于是就换一种方式,存储到常量池里,以便于虚拟机查找。

运行时常量池

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

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-08 11:07:41  更:2021-08-08 11:08:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/11 4:13:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码