在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剩余空间容量的百分比,减少为释放空间所导致的垃圾收集
查看该区值:
标签:管理,虚拟机,线程,内存,JVM,空间,Metaspace From: https://www.cnblogs.com/ilovebath/p/18163778