jvm(三)内存区域控制参数及对应溢出异常

8 篇文章 0 订阅

开发过程中,或程序运行过程中每次遇到OutOfMemory异常或GC异常或StackOverflowError异常

我们都是一堆参数乱配,都把值调大,只是大体知道是跟jvm内存分配有关,具体应该怎么

调,对应的异常应该调整那些参数,或者换句话说,jvm内存分配区域中都分别对应那些参数

大多数情况下都是不知道的,只是把相关的参数跳上去,预期结果都是应该起作用,到底能不能

起作用,自己心里也没底。

 

下面就来说一下jvm堆、栈、方法区等内存区域对应的参数,及每个区域可能抛出的异常类型,

发生异常的场景分析。

一、参数类型

  1. 堆空间参数
  2. 栈空间参数
  3. 本地方法栈
  4. 方法区空间参数------->元空间参数
  5. 本机直接内存参数
  6. 计数器

二、异常类型

  1. OutOfMemory异常
  2. StackOverflowError异常
  3. Memory Leak 异常

三、辅助参数说明

  1. -XX:+HeapDumpOnOutOfMemoryError 打印堆内存异常时打印出快照信息
  2. -XX:+HeapDumpPath 快照输出路径
  3. -Xmn指定eden区的大小 -XX:SurvirorRation来调整幸存区的大小
  4. -XX:PretenureSizeThreshold设置进入老年代的阀值

四、参数说明、对应场景的异常

1.堆内存参数(共享)

  • -Xms:堆最小值(新生代和老年代之和)
  • -Xmx:堆最大值(新生代和老年代之和)

当最小值=最大值时,这时堆内存是不可扩展的。

例:-Xms80M -Xmx80M 

通常将-Xmx和-Xms设置为一样的大小来减少gc的

堆内存不足时抛出OutOfMemoryError异常。

设置新生代内存大小

-Xmn256m  :-Xmn 是将NewSize与MaxNewSize设为一致。256m

等同于:-XX:NewSize=256m    -XX:MaxNewSize=256m

通过新生代与老年代内存比值来设置新生代内存大小

-XX:NewRatio=3

设置新生代(包括Eden和两个Survivor区)与老年代的比值。设置为3,则新生代与老年代所占比值为1:3,新生代占整个堆栈的1/4

Survivor内存大小设置

-XX:SurvivorRatio=8

设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个新生代的1/10

Eden内存大小设置

新生代减去2*Survivor的内存大小就是Eden的大小

Old Generation(老年的)的内存大小设置

堆内存减去新生代内存

老年代初始内存为:512M-256M=256M

老年代最大内存为:1G-256M=768M

 设置新生代代对象进入老年代的年龄

-XX:MaxTenuringThreshold=15

设置垃圾最大年龄。如果设置为0的话,则新生代对象不经过Survivor区,直接进入老年代。对于老年代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则新生代对象会在Survivor区进行多次复制,这样可以增加对象再新生代的存活时间,增加在新生代即被回收的概论。

 

2.栈内存参数(线程私有)

-Xss

例:-Xss128k

单线程下无论栈帧太大还是栈容量太小,及引用深度超过

虚拟机允许深度都会抛出StackOverflowError

每个方法压入栈的帧大小是不一致的。

每个线程都会产生一个栈。在相同物理内存下,减小这个值能生成更多的线程。如果这个值太小会影响方法调用的深度。

 

多线程下当每个线程分配栈帧太大内存不能够扩展时抛出

OutOfMemoryError异常

3.方法区参数 (程序共享)元空间内存

(jdk1.8内存模型已移除该配置,对应的新增了方法区的实现“元空间”)

-XX:PermSize方法区内存最小值

-XX:MaxPermSize 方法区内存最大值

 

各个线程共享的内存区域,主要用来存储类的元数据、

常量、静态变量、即时编译器编译后的代码等数据

例:-XX:PermSize=20M -XX:MaxPermSize=20M

 

异常类型 OutOfMemoryError :

原因:常量过多,或代理反射等使用频繁

 

元空间(Metaspace)(JDK8)
-XX:MetaspaceSize=128m

-XX:MaxMetaspaceSize=512m(JDK8),JDK8的持久代几乎可用完机器的所有内存,同样设一个128M的初始值,512M的最大值保护一下。

 

 一个新的参数 (MaxMetaspaceSize)可以使用。允许你来限制用于类元数据的本地内存。如果没有特别指定,元空间将会根据应用程序在运行时的需求动态设置大小

4.本机直接内存参数

-XX:MaxDirectMemorySize

例:-XX:MaxDirectMemorySize=10M

不足时抛出OutOfMemory异常

此参数的含义是当Direct ByteBuffer分配的堆外内存到达指定大小后,即触发Full GC。注意该值是有上限的,默认是64M,最大为sun.misc.VM.maxDirectMemory(),在程序中中可以获得-XX:MaxDirectMemorySize的设置的值。
使用NIO可以api可以使用直接内存。

5.其它设置

-XX:MaxHeapFreeRatio=70

GC后java堆中空闲量占的最大比例,大于该值,则堆内存会减少

 

-XX:MinHeapFreeRatio=40

GC后java堆中空闲量占的最小比例,小于该值,则堆内存会增加

 

-XX:PretenureSizeThreshold=1024

(单位字节)对象大小大于1024字节的直接在老年代分配对象

 

-XX:TLABWasteTargetPercent =1

TLAB占eden区的百分比 默认1%

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值