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与GC(一) -> 正文阅读

[Java知识库]JVM与GC(一)


这个系列会很长,先讲理论,后实战,设计到的内容也是JVM那本书里比较基础的,大神请忽略这篇文章,图也大多是盗的

JVM内存模型

JVM规范之JVM内存

在这里插入图片描述下图是这几个区域会涉及到的配置参数和异常,需要注意的是 虚拟机栈 其实就是人们平常所说的栈区,方法区是JDK1.8之前的叫法,JDK1.8之后称为元空间
针对的设置参数也不同 1.7是:X:PermSize:16MXX:MaxPermSize64M 这两个
1.8是:X:MetaspaceSize=16M
XX:MaxMetaspaceSize=64M
这两个
在这里插入图片描述

版本内存结构差异

1.7内存结构介绍

五个部分 方法区 堆 栈 本地方法栈 程序计数器
在这里插入图片描述

1.8内存结构介绍

对比1.7 没有了方法区 在1.8里叫元空间 位置也变了 变到了本地内存
在这里插入图片描述
对于Java8,HotSpots取消了永久代,那么是不是就没有方法区了呢?
当然不是,方法区只是一个规范,只不过它的实现变了。 在Java8中,元空间(Metaspace)登上舞台,方法区存在于元空间(Metaspace)。同时,元空间不再与堆连续,而且是 存在于本地内存(Native memory)。
方法区Java8之后的变化
移除了永久代(PermGen),替换为元空间(Metaspace) 永久代中的class metadata(类元信息)转移到了native memory(本地内存,而不是虚拟机) 永久代中的interned Strings(字符串常量池) 和 class static variables(类静态变量)转移到了Java heap 永久代参数(PermSize MaxPermSize)-> 元空间参数(MetaspaceSize MaxMetaspaceSize)

Java8为什么要将永久代替换成Metaspace?
字符串存在永久代中,容易出现性能问题和内存溢出。 类及方法的信息等比较难确定其大小,因此对于永久代的大小指定比较困难,太小容易出现永久代溢出,太 大则容易导致老年代溢出。 永久代会为 GC 带来不必要的复杂度,并且回收效率偏低。 Oracle 可能会将HotSpot 与 JRockit 合二为一,JRockit没有所谓的永久代。

1.8内存详解

上图是粗略的比较了1.7和1.8的区别,这个图是详细的1.8的内存结构,虚拟机栈我们都知道 会有栈帧 做过算法的朋友都知道如果一个回溯算法做不好的话 就会出现栈溢出,而为什么可以回溯也是因为栈帧有顺序的压入和弹出
在这里插入图片描述

参数配置

整体堆内存空间的分配
上代码
下面这段代码 运行的时候没有设置任何的JVM参数
我们看下默认情况内存能给到多少
还有就是totalMemory的弹性伸缩问题

public static void main(String[] args) {//main方法也是放在Method方法区域中的
        /**
         * student(小写的)是放在主线程中的Stack区域中的
         * Student对象实例是放在所有线程共享的Heap区域中的
         */
      //  Student student = new Student("spark");
        //不设置JVM参数 看看内存
        System.out.println(Runtime.getRuntime().maxMemory()/1024/1024);
        System.out.println(Runtime.getRuntime().freeMemory()/1024/1024);
        System.out.println(Runtime.getRuntime().totalMemory()/1024/1024);
        /**
         * 首先会通过student指针(或句柄)(指针就直接指向堆中的对象,句柄表明有一个中间的,student指向句柄,句柄指向对象)
         * 找Student对象,当找到该对象后会通过对象内部指向方法区域中的指针来调用具体的方法去执行任务
         */
        //student.sayHello();
    }

结果如下 也就是说 我这个16G的电脑 在不设置任何JVM参数的情况下 最大内存给到了3596M 也就是3.5G
但是目前的总内存使用情况 仅仅有243M
那么现在我们在代码里加入这样一句
在这里插入图片描述分配了200M给这个程序,这就是弹性伸缩了,在没有超过最大内存的时候 total是会弹性的根据已经创建出的内存空间 合理分配,不会一次性直接拿来3596左右的内存,但是在实际生产中我们应该尽量避免这种抖动,

byte[] b=new byte[1024*1024*200];
执行结果
3596
238
444

所以在正常生产环境下 我们应该设置Xmx和Xms设置成一样的值

 -Xmx1344M -Xms1344M

下图是堆空间对应的JVM参数
在这里插入图片描述新生代与老年代比例
配置新生代和老年代堆结构占比 默认 -XX:NewRatio=2 , 标识新生代占1 , 老年代占2 ,新生代占整个堆的1/3 修改占比 -XX:NewPatio=4 , 标识新生代占1 , 老年代占4 , 新生代占整个堆的1/5
新生代----eden和s0 s1比例
Eden空间和另外两个Survivor空间占比分别为8:1:1 可以通过操作选项 -XX:SurvivorRatio 调整这个空间比例。
比如 -XX:SurvivorRatio=8 几乎所有的java对象都在Eden区创建, 但80%的对象生命周期都很短,创建出来就会被销
设置8 那就是 8:1:1 eden:s0:s1
如果设置4 那就4:1:1 也就是说eden占内存的4/6 s0s1各占1/6

这里我们需要思考 在什么情况下需要修改新生代老年代的比例
eden和s0s1的比例

年轻代 老年代内存分配过程

1.new的对象先放在伊甸园区。该区域有大小限制
2.当伊甸园区域填满时,程序又需要创建对象,JVM的垃圾回收器将对eden进行垃圾回收(Minor GC),将伊 甸园区域中不再被其他对象引用的额对象进行销毁,再加载新的对象放到伊甸园区
3.然后将伊甸园区中的剩余对象移动到幸存者0区
4.如果再次触发垃圾回收,此时上次幸存下来的放在幸存者0区的,如果没有回收,就会放到幸存者1区
5.如果再次经历垃圾回收,此时会重新返回幸存者0区,接着再去幸存者1区。
6.如果累计次数到达默认的15次,这会进入养老区。 可以通过设置参数,调整阈值 -XX:MaxTenuringThreshold=N
7.养老区内存不足是,会再次出发GC:Major GC 进行养老区的内存清理
8.如果养老区执行了Major GC后仍然没有办法进行对象的保存,就会报OOM异常
先触发YGC/MinorGC去回收年轻代,eden中回收不了的对象放入S0/S1(这里总会有一个是空着的),比如上次回收的对象放到了S0 这次回收S0里头的对象如果还是回收不掉那就转移到S1并且Age加1
在这里插入图片描述
在这里插入图片描述
下图的老年代已经出现了对象 这种对象有两种可能 要么是eden区回收的时候想放入S0/S1但是对象太大了 放不进去 就会直接进入老年代,还有一种就是年轻代回收的时候一直回收不掉 在S0和S1之间闪转腾挪 最后Age达到15进入了老年代

在这里插入图片描述

1.8GC类别

在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 21:56:32  更:2021-07-16 21:57:21 
 
开发: 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/8 8:10:25-

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