JVM调优—内存区域

Posted wx5add7776993de

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM调优—内存区域相关的知识,希望对你有一定的参考价值。


一、jvm内存区域

关于jvm内存模型的具体总结,这篇博客有详细的总结:
​​​jvm内存区域​

JVM调优—内存区域_垃圾回收


我们主要关注jvm中最主要的三块内存 — 堆,栈,方法区,而最容易最经常出现的内存错误OutOfMemoryError就很经常的很频繁的出现在这三个区域,因而,值得我们深究

1.堆

概念

java堆是jvm中所占内存最大的一块区域,是被所有线程共享的一块区域,堆也是垃圾收集器重点照顾的区域,也有gc堆之称

作用

所有的对象实例和数组都要在堆上分配内存

堆分区

根据垃圾回收的次数,堆又可分为新生代和老年代

新生代又可分为Eden空间、From Survivor空间(s0区)、To Survivor空间(s1区)so和s1区是两个大小相等且可以角色互换的区域,垃圾回收算法中的复制算法,利用的两个空间就是s0区和s1区

新生代中所占空间比,Eden:s0:s1 = 8:1:1

JVM调优—内存区域_java_02

对象新new出来时,会存放在堆中Eden区,在一次垃圾回收后,如果对象还存活之后会进入s0区或s1区中的一个,当垃圾回收次数达到15次(jvm默认垃圾回收次数达到15次便进入老年代)进入老年代

堆内存OutOfMemoryError

如果在堆中内有内存完成实例分配,并且堆也无法再扩展时,则将抛出OutOfMemoryError异常

堆参数调优

// -xx:一般是对系统(jvm)级别的设置
// 非-xx,一般是应用级别的设置
// +:启用
// -:禁用

// 格式:unit:单位 GB的“g”,MB的“m”和KB的“k”
// -Xms<heap size>[unit]

-Xms设置堆的最小空间大小。

-Xmx设置堆的最大空间大小。

-XX:NewSize设置新生代最小空间大小。

-XX:MaxNewSize设置新生代最大空间大小。

-XX:PermSize设置永久代最小空间大小。

-XX:MaxPermSize设置永久代最大空间大小。

-Xss设置每个线程的堆栈大小

-XX:+UseParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。

-XX:ParallelGCThreads=20:配置并行收集器的线程数,:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

2.方法区

概念

与java堆一样,也是线程共享的内存区域,也称为永久代(jdk1.8前),jdk1.8后
推出metaspace(本地内存)关于metaspace可以参考这篇推文 ​​​metaspace总结​

作用

存储已被虚拟机加载的类信息,静态变量,常量

运行时常量池

运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用

方法区参数调优

-XX:PermSize=64MB 最小尺寸,初始分配 (jdk1.8会出现警告)

-XX:MaxPermSize=256MB 最大允许分配尺寸,按需分配 (jdk1.8会出现警告)

XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 设置垃圾不回收 默认大小

-server选项下默认MaxPermSize为64m

-client选项下默认MaxPermSize为32m

3.栈

java虚拟机栈

概念

线程私有,生命周期和线程一样,描述java方法执行的内存模型

分区

  • 局部变量表
    存储方法形参和内部定义的局部变量
  • 操作数栈
    存储方法执行过程中计算的中间结果
  • 帧数据区
    保存访问常量池的指针

本地方法栈

概念

本地方法栈为虚拟机执行本地方法服务

内存错误

  • StackOverflowError
    线程请求的栈深度大于虚拟机所允许的深度
  • OutOfMemoryError
    如果在栈中内有内存完成实例分配,并且栈也无法再扩展时,则将抛出OutOfMemoryError异常

4.处理OOM

dump形式处理oom

JVM提供了一些参数,保证程序在内存溢出的时候能够将当前的堆信息保存在磁盘上,以至于你事后能更具这个快照信息找到问题根源:

-XX:+HeapDumpOnOutOfMemoryError //表示dump堆信息到磁盘

-XX:HeapDumpPath=./java_pid<pid>.hprof //dump文件的文件路径和文件名,可以是任意的文件名,如果文件名中包含<pid>,会被替换成JVM应用的pid

-XX:OnOutOfMemoryError="< cmd args >;< cmd args >" //是在发送内存溢出的时候执行的命令,例如:我想在内存溢出的时候重启服务器。-XX:OnOutOfMemoryError="shutdown -r"

-XX:+UseGCOverheadLimit //设置GC消失时间的百分比限制,如果GC时间过长,超过了这个限制,那么就会触发内存溢出错误。

dump概述

Heap Dump 是 Java进程所使用的内存情况在某一时间的一次快照。以文件的形式持久化到磁盘中。

Heap Dump的格式有很多种,而且不同的格式包含的信息也可能不一样。但总的来说,Heap Dump一般都包含了一个堆中的Java Objects, Class等基本信息。同时,当你在执行一个转储操作时,往往会触发一次GC,所以你转储得到的文件里包含的信息通常是有效的内容(包含比较少,或没有垃圾对象了) 。

Heap Dump 包含的信息

  • 所有的对象信息
    对象的类信息、字段信息、原生值(int, long等)及引用值
  • 所有的类信息
    类加载器、类名、超类及静态字段
  • 垃圾回收的根对象
    根对象是指那些可以直接被虚拟机触及的对象
  • 线程栈及局部变量
    包含了转储时刻的线程调用栈信息和栈帧中的局部变量信息

jvm参数获取dump

  1. -XX:+HeapDumpOnOutOfMemoryError
    当OutOfMemoryError发生时自动生成 Heap Dump 文件。
  2. -XX:+HeapDumpBeforeFullGC
    当 JVM 执行 FullGC 前执行 dump。
  3. -XX:+HeapDumpAfterFullGC
    当 JVM 执行 FullGC 后执行 dump。
  4. -XX:+HeapDumpOnCtrlBreak
    交互式获取dump。在控制台按下快捷键Ctrl + Break时,JVM就会转存一下堆快照。
  5. -XX:HeapDumpPath=d:\\test.hprof
    指定 dump 文件存储路径。


以上是关于JVM调优—内存区域的主要内容,如果未能解决你的问题,请参考以下文章

JVM调优—内存区域

jvm原理及性能调优系列(自动内存管理机制)

JVM调优—GC调优

JVM快速调优手册之一: 内存结构(堆内存和非堆内存)

JVM快速调优手册之一: 内存结构(堆内存和非堆内存)

jvm调优的学习