JVM垃圾收集器(Java Garbage Collection)。本教程均在JDK1.8+HotSpot为例来讲解的.

先来看看Java7的:

编辑

再来看看Jva8的

编辑

从上图中我们可以看出,java8之后换成了元空间。那么怎么证明,堆区是有新生代、永久代、元空间三部分组成的呢?OOM这个错误我们都熟悉,那么怎么手动制造出一个OOM呢?如果16G的物理内存,JVM堆内存能够分到多少G的内存空间呢?我们带着这些疑问来一起学习吧

在Java8中,永久带已经被移除了,被一个称为元空间的区域所取代。元空间的本质和永久带类似。

元空间与永久带之间最大的区别在于:

永久带使用的是JVM的堆内存空间,但是java8以后的元空间并不是虚拟机中的空间,而是使用了本机的物理内存空间的。

因此,默认情况下,元空间大小仅受到本地内存大小的限制。类的元数据放入native memory,字符串常量池和静态类变量存放在java堆区中。这样可以加载多少类的元数据,就不在由MaxPermSize控制了,而是由系统的实际可用空间来控制。

Java默认堆区空间大小是物理内存的六十四分之一(1/64).默认最大堆空间是物理内存的1/4

想要对JVM调优的话,就先要知道自己的家底。默认情况下,当前服务的JVM最大和最小内存是多少呢?怎么查看呢?

我们可以使用Runtime这个类来查看。具体代码如下:

编辑

运行结果:

编辑

来看看凯哥本子上物理内存大小:

编辑

可以看到是24GB。

从打印的结果,我们看知道,凯哥本子上的JVM最大内存是5.4个G。也就是大约等于物理内存的1/4

JVM最小内存就是:368。大约是物理内存的1/64.

是不是证明了JVM默认堆内存最大值占用物理内存的1/4,最小值占用物理内存的1/64。没有忽悠,没有骗人吧。

编辑

看到了吗?totoalMemory方法和maxMemory方法都是native的。在前面,我们讲解JVM体系图的时候,讲解了native关键字修饰的方法,这里就不赘述了。

代码证明堆内存空间就是新生代、老年代、元空间三个区域:

在idea中通过VM options参数来操作

编辑

找到需要修改的类,然后在VM options,添加参数。如下图:

编辑

输入如下参数:-Xms1024m -Xmx1024m -XX:+PrintGCDetails

编辑

堆内存调优参数说明:

命令

描述

-Xms

设置初始分配大小,默认物理内存的1/64

-Xmx

最大分配内存,默认为物理内存的1/4

-XX:+PrintGCDetails

输出详细的GC处理日志

修改好了之后,重新运行程序,我们看看控制台打印的信息:

编辑

修改后,我们发现堆内存的最大和最小的值是相等的。需要说明一点,在生产环境中,我们最好也把最大和最小值设置一样。这样可以减少空间差距切换从而影响了程序的稳定健壮性。

在上图2部分区域,就是打印出了jvm的详细信息。我们可以明显的看到如下几个数据:

PSYoungGen、ParOldGen、Metaspace这三个区域,正好就是我们之前文章说的,新生代、老年代、元空间这三个区域。这是逻辑上区分的。

在物理上区分是2个,分别是新生代和老年代,怎么证明呢?

编辑

还记得我们参数设置的是1024m吧。把新生代和老年代的total相加,是不是就是打印出最大和最小堆内存的值?

再来看看新生代和老年代空间占用比例:305664/699392是不是于等于1/2。

怎么证明新生代是有伊甸园区、from区、to区三部分组成呢?三部分占用比例怎么证明是8/1/1呢?请看下图:

编辑

是不是有三个区域。占用空间分别是:26214/43520/43520.是不是就是8/1/1?

现在再回过头,来看看堆内存,是不是更清晰了。

编辑

通过修改堆参数,模拟出OOM问题

思路:

写个while(true)死循环,通过设置JVM的参数,设置小一点。比如8M,然后执行就会出现OOM。或者new一个字节数组,大于配置的参数就可以。比如设置的堆内存大小是8M,那么byte[] bytes =new byte[10*1024*1024]; //10M的对象。一定会OOM

编辑

-Xms8m -Xmx8m -XX:+PrintGCDetails

编辑

运行后,查看控制台打印信息.

编辑

是不是看到了熟悉的

[Full GC (Allocation Failure) Exception in thread "main" java.lang.OutOfMemoryError: Java heap space。

下一篇文章预告:GC收集日志信息分析。欢迎大家和凯哥(凯哥java:kaigejava)一起继续学习。

JVM笔记八-堆参数调优的更多相关文章

  1. JVM 堆参数调优 (四)

    堆参数调优 1.堆的结构 JAVA7 堆逻辑上分为:新生区.养老区.永久区:实际上堆只有新生区.养老区: Minor GC:轻量的垃圾回收:   Major GC(Full GC):重量级垃圾回收. ...

  2. JVM内存结构、参数调优和内存泄露分析

    1. JVM内存区域和参数配置 1.1 JVM内存结构 Java堆(Heap) Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建.此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都 ...

  3. JVM内存模型及参数调优

    堆.栈.方法区概念区别 1.堆 堆内存用于存放由new创建的对象和数组.在堆中分配的内存,由java虚拟机自动垃圾回收器来管理.根据垃圾回收机制的不同, Java堆有可能拥有不同的结构,最为常见的就是 ...

  4. 深入探究jvm之GC的参数调优

    在上一篇博客记录了GC的算法及种类,这篇博客主要记录一下GC的参数如何调整以提高jvm的性能. 一.堆的回顾: 堆的内存空间总体分为新生代和老年代,老年代存放的老年对象,新构造的对象分配在eden区中 ...

  5. (转)JVM参数调优八大技巧

    这里和大家分享一下JVM参数调优的八条经验,JVM参数调优,这是很头痛的问题,设置的不好,JVM不断执行FullGC,导致整个系统变得很慢,网站停滞时间能达10秒以上,相信通过本文的学习你对JVM参数 ...

  6. JVM:参数调优

    JVM:参数调优 本笔记是根据bilibili上 尚硅谷 的课程 Java大厂面试题第二季 而做的笔记 前言 查看 JVM 系统默认值:使用 jps 和 jinfo 进行查看 -Xms:初始堆空间 - ...

  7. JVM探究 面试题 JVM的位置 三种JVM:HotSpot 新生区 Young/ New 养老区 Old 永久区 Perm 堆内存调优GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数法

    JVM探究 面试题: 请你弹弹你对JVM的理解?Java8虚拟机和之前的变化更新? 什么是OOM?什么是栈溢出StackOverFlowError?怎么分析 JVM的常用调优参数有哪些? 内存快照如何 ...

  8. JVM性能参数调优实践,不会执行Full GC,网站无停滞

    原文来自:http://bbs.csdn.net/topics/310110257 本文只做整理记录,供个人学习. 1 JVM参数调优是个很头痛的问题,设置的不好,JVM不断执行Full GC,导致整 ...

  9. SpringBoot-内部运行jvm参数调优

    SpringBoot JVM参数调优 这个根据服务器的内存大小,来设置堆参数. -Xms :设置Java堆栈的初始化大小 -Xmx :设置最大的java堆大小 实例参数-XX:+PrintGCDeta ...

  10. 性能测试三十六:内存溢出和JVM常见参数及JVM参数调优

    堆内存溢出: 此种溢出,加内存只能缓解问题,不能根除问题,需优化代码堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,就会出现内存溢出OutOfMemory:Java h ...

随机推荐

  1. IOS浏览器返回刷新页面

    $(function () { var isPageHide = false; window.addEventListener('pageshow', function () { if (isPage ...

  2. 手把手教你解决spring boot导入swagger2版本冲突问题,刘老师教编程

    手把手教你解决spring boot导入swagger2版本冲突问题 本文仅为个人理解,欢迎大家批评指错 首先Spring Boot 3 和 Swagger 2 不兼容.在 Spring Boot 3 ...

  3. css-渐变简约的登录设计

    代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  4. 网易数帆实时数据湖 Arctic 的探索和实践

    作者 | 蔡芳芳 采访嘉宾 | 马进 网易数帆平台开发专家 数据中台也要从离线为主走向实时化,湖仓一体是第一步. 数据从离线到实时是当前一个很大的趋势,但要建设实时数据.应用实时数据还面临两个难题.首 ...

  5. linux mysql 允许进行远程连接 比如 navicat

    出于安全方面考虑默认只允许本机(localhost, 127.0.0.1)来连接访问.所以开启远程访问权限.登录mysqlmysql -uroot -pxxxxxx 1:GRANT ALL PRIVI ...

  6. [oeasy]python0021_python虚拟机的位置_可执行文件_转化为字节形态

    ​ 程序本质 回忆上次内容 ​\n​​ 就是换行 他对应着 ​​ascii​​ 字符的代码是(​​10​​)​​10进制​​ 他的英文是 LF,意思是​​Line Feed​​ 我们可以在<安徒 ...

  7. 一文揭开JDK21虚拟线程的神秘面纱

    虚拟线程快速体验 环境:JDK21 + IDEA public static void main(String[] args) { try (var executor = Executors.newV ...

  8. java集合解析

    1,java集合体系 2,Colletion集合 子接口有List和Set (1)List接口:ArrayList,Vector,LinkedList list是collection接口的子接口,特点 ...

  9. Docker 基于Dockerfile创建镜像实践

    需求描述 简单说,就是创建一个服务型的镜像,即运行基于该镜像创建的容器时,基于该容器自动开启一个服务.具体来说,是创建一个部署了nginx,uwsgi,python,django项目代码的镜像,运行基 ...

  10. openGL之多线程渲染

    随着Vulkan的引入,我们的图形技术的发展到达了一个新的顶点,但是呢,我们的老干爹OpenGL作为落日余晖,他在一些Vulkan才有的新功能上,也提供了一些支持,现在我们来讨论一下OpenGL之多线 ...