一、JVM内存空间介绍
1. JDK8.0之前的jvm空间
- 方法区(永久代) : 存储类的行为和共同属性,以及对应的常量池
- 堆空间:存储创建的对象空间
- 本地方法栈
- 虚拟机栈
- 程序计数器
2. jdk8.0之后的元空间
在jdk8.0取消永久代,而是使用元空间,这里的元空间其实是堆外空间,不属于jvm内存空间,也就是说这个是本地内存,直接归操作系统管理,不归jvm管理。
这样做的好处是什么?
- 我们需要明白的是jvm内存空间其实也是一个进程空间,如果我们需要向操作系统写入文件,那么就需要将数据先写入堆空间,然后再由用户态将数据复制到内核态,然后内核态再去在socket缓存区进行拷贝到磁盘中。
参见:https://blog.csdn.net/qq359605040/article/details/128533324
3. 常量池问题
Java6和6之前,常量池是存放在方法区(永久代)中的。
Java7,将常量池是存放到了堆中。
Java8之后,取消了整个永久代区域,取而代之的是元空间。运行时常量池和静态常量池存放在元空间中,而字符串常量池依然存放在堆中。
3. 如何操作堆外空间
通过DirectByteBuffer优化
二、JVM常用参数解析
2.1 设置堆栈空间
-Xss:栈内存容量。
-Xms:堆最小内存容量。
-Xmx:堆最大内存容量,通常和-Xms设置一样,防止运行时扩容产生的影响。
我们常常会遇到如下的jvm错误
- StackOverflowError
StackOverflowError是表示栈空间太小,因此可以使用-Xss修改栈空间 一般是 -Xss512kb。
如果我们的机器是4G,但是有很多线程,如果-Xss空间很大,这样会导致虚拟机栈空间会很大。
因此这样可以减小 -Xss - OutOfMemoryError
堆空间过小,可以使用-Xmm4g 调大
2.2 设置元空间
-XX:MetaspaceSize=256M 初始大小
-XX:MaxMetaspaceSize=256M 最大发生full gc的空间,但是并不是最大的空间。
有一个问题,现在的元空间应该设置多少合适,现在元空间主要存放一些类的字节码文件,一些包装类常量池,以及一些信息。因此使用256M是足够足够了,因为一个class文件也才10kb不到,100个class文件也就1M左右,那如果我们需要使用堆外空间作还缓存使用的话,就需要根据实际情况调整。