JVM内存管理

池塘里洗澡的鸭子 / 2024-04-29 / 原文

  在JVM初识中提到之所以在程序和操作系统之间增加JVM,就是JVM有些内存管理的特性直接在操作系统上实现有些费劲。那么JVM的内存管理是怎样的呢?

  应用程序运行大致如下过程:                   

                

   其中内存部分就是运行时数据区,即虚拟机的内存结构。                                   

                

                

                 

  其中线程私有的:1)程序计数器  2)虚拟机栈  3)本地方法栈

  线程共享的:1)堆 2)方法区

  直接内存也是线程共享,但其不属于运行时数据区的一部分。下面就内存部分,分结构介绍:

  一、计数器PC Register:也叫PC寄存器,是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。

                

  二、虚拟机 Stacks

                

    该结构可配置大小,可以优化的一个点:

      -Xss jvm启动的每个线程分配的内存大小:

        Linux/x64 (64-bit): 1024 KB
        macOS (64-bit): 1024 KB
        Oracle Solaris/x64 (64-bit): 1024 KB
        Windows: The default value depends on virtual memory
          -Xss1m
          -Xss1024k
          -Xss1048576

    局部变量:

                

                     

  三、Native Method Stacks:其为为虚拟机使用到的本地(Native) 方法服务。

    在Java虚拟机规范中,对本地方法栈这块区域,与Java虚拟机栈一样,规定了两种类型的异常:
      (1)StackOverFlowError :线程请求的栈深度>所允许的深度。
      (2)OutOfMemoryError:本地方法栈扩展时无法申请到足够的内存。

  四、Heap

    1)堆大小设置

      内存大小-Xmx/-Xms,使用示例: -Xmx20m -Xms5m

    堆分配——分配对象的流程:

                

                

                

  五、Metaspace

    其参数设置如下:

    -XX:MetaspaceSize,初始空间大小,达到该值就会触发垃圾收集进行类型卸载,同时GC会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过MaxMetaspaceSize时,适当提高该值。

    -XX:MaxMetaspaceSize,最大空间,默认是没有限制的。如果没有使用该参数来设置类的元数据的大小,其最大可利用空间是整个系统内存的可用空间JVM也可以增加本地内存空间来满足类元数据信息的存储。但是如果没有设置最大值,则可能存在bug导致Metaspace的空间在不停的扩展,会导致机器的内存不足;进而可能出现swap内存被耗尽;最终导致进程直接被系统直接kill掉。如果设置了该参数,当Metaspace剩余空间不足,会抛出:java.lang.OutOfMemoryError: Metaspace space

    -XX:MinMetaspaceFreeRatio,在GC之后,最小的Metaspace剩余空间容量的百分比,减少为分配空间所导致的垃圾收集

    -XX:MaxMetaspaceFreeRatio,在GC之后,最大的Metaspace剩余空间容量的百分比,减少为释放空间所导致的垃圾收集

     查看该区值: