jvm性能调优-内存溢出

jvm性能调优-内存溢出_第1张图片 在Java中,和内存相关的问题主要有两种,内存溢出内存泄漏

内存溢出(Out Of Memory) :就是申请内存时,JVM没有足够的内存空间。通俗说法就是去蹲坑发现坑位满了。

内存泄露 (Memory Leak):就是申请了内存,但是没有释放,导致内存空间浪费。通俗说法就是有人占着茅坑不拉屎。

在JVM的几个内存区域中,除了程序计数器外,其他几个运行时区域都有发生内存溢出(OOM)异常的可能。

jvm性能调优-内存溢出_第2张图片

堆内存溢出

要解决这个内存区域的异常,常规的处理方法是首先通过内存映像分析工具(如JProfiler、Eclipse Memory Analyzer、MAT等)对Dump出来的堆转储快照进行分析。

溢出场景:内存泄漏、非内存泄漏

解决方案:通过工具分析,合理配置参数

栈内存溢出

java虚拟机规范:

    如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError

    如果虚拟机的栈内存允许动态扩展,当无法申请到足够内存时,将抛出OutOfMemoryError

栈能够分配的内存:

    = 机器总内存 - 操作系统内存 - 堆内存 - 方法区内存 - 程序计数器内存 - 直接内存

方法区溢出

方法区:是被线程共享的,用来存储被虚拟机加载的类型信息、常量、静态变量等

不同jdk版本的方法区存放结构不同,相同的代码报错也可能不同

报错场景:常量池里对象太大、加载的类的"种类"太多、jsp项目、脚本语言动态类加载

如何避免方法区溢出:

        根据JDK版本,为常量池保留足够空间  >=jdk7:设大Xms、Xmx

        防止类加载过多导致的溢出 <=jdk7:设大PermSize、MaxPermSize

              >jdk8:留空元空间相关的配置,或设置合理大小的元空间

jvm性能调优-内存溢出_第3张图片

jvm性能调优-内存溢出_第4张图片 

直接内存溢出

直接内存:不属于虚拟机运行时数据区;是一块由操作系统直接管理的内存,也叫堆外内存;可以使用Unsafe或ByteBuffer分配直接内存;可用-XX:MaxDirectMemorySize控制,默认是0,表示不限制

为什么要用直接内存? 当然性能强于堆内存

直接内存使用场景

1.有很大的数据需要存储,生命周期很长

2.频繁的IO操作,比如并发网络通信

总结:

直接内存也叫堆外内存,IO效率较高

可以用Unsafe类或ByteBuffer来分配

你可能感兴趣的:(jvm,性能调优,jvm,java)