JVM内存参数的学习之三
背景
研究启动性能时, 顺便看到了jmap -heap 1 的部分信息
看到:
MinHeapFreeRatio、MaxHeapFreeRatio
自己突然以为是 Percentage的参数, 恍惚了好久.
才发现自己对内存的学习不够, 所以想多学习一下.
参数解释
MinHeapFreeRatio:
空闲堆空间的最小百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,
值的区间为0到100,默认值为 40。如果HeapFreeRatio < MinHeapFreeRatio,则需要进行堆扩容,扩容的时机应该在每次垃圾回收之后。
MaxHeapFreeRatio :
空闲堆空间的最大百分比,计算公式为:HeapFreeRatio =(CurrentFreeHeapSize/CurrentTotalHeapSize) * 100,
值的区间为0到100,默认值为 70。如果HeapFreeRatio > MaxHeapFreeRatio,则需要进行堆缩容,缩容的时机应该在每次垃圾回收之后。
来源:
参数默认值
如果启动参数为:
"-XX:MaxRAMPercentage=80.0","-XX:MinRAMPercentage=50.0"
参数值应该是默认的:
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 25891438592 (24692.0MB)
NewSize = 169148416 (161.3125MB)
MaxNewSize = 8630435840 (8230.625MB)
OldSize = 338362368 (322.6875MB)
如果关闭自适应的话:
"-XX:-UseAdaptiveSizePolicy","-XX:MaxRAMPercentage=80.0","-XX:MinRAMPercentage=50.0"
发现这个参数值并不会发生变化
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 25891438592 (24692.0MB)
NewSize = 169148416 (161.3125MB)
MaxNewSize = 8630435840 (8230.625MB)
OldSize = 338362368 (322.6875MB)
增加初始化的设置时
"-XX:InitialRAMPercentage=75.0","-XX:MaxRAMPercentage=75.0","-XX:MinRAMPercentage=75.0"
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 22548578304 (21504.0MB)
NewSize = 7516192768 (7168.0MB)
MaxNewSize = 7516192768 (7168.0MB)
OldSize = 15032385536 (14336.0MB)
感觉增加初始化 InitialRAMPercentage 非常管用,会自动分配堆区设置, 并且能够将old区域 固定下来.
如果不设置 InitialRAMPercentage时
"-XX:MaxRAMPercentage=75.0","-XX:MinRAMPercentage=75.0"
Heap Configuration:
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 22548578304 (21504.0MB)
NewSize = 234881024 (224.0MB)
MaxNewSize = 11274289152 (10752.0MB)
OldSize = 234881024 (224.0MB)
但是这个时候内存的分配不是严格的 1:2配比的new和old old区域一开始很小. 感觉这样并不是很优秀.
可以增加几个内存参数对象的变量设置.
"-XX:InitialRAMPercentage=75.0","-XX:MaxRAMPercentage=75.0","-XX:MinRAMPercentage=75.0","-XX:SurvivorRatio=3","-XX:NewRatio=1"
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 22548578304 (21504.0MB)
NewSize = 11274289152 (10752.0MB)
MaxNewSize = 11274289152 (10752.0MB)
OldSize = 11274289152 (10752.0MB)
参数的理解
JVM的参数其实很复杂.
建议还是 最大最小区域保持一致, 这样的话就不会因为 freeMemory的原因
导致堆区被收缩和扩张因为性能衰退.
毕竟操作系统进行内存的收缩和扩展是要耗费资源和时间的.
不改容器内启动脚本实现不同参数的方法
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: myapp
name: myapp-deployment
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- image: myapp:v1.0
ports:
- containerPort: 5200
name: myapp
command: ["java","-Djava.security.egd=file:/dev/./urandom","-Dloader.path=./server/runtime/3rd,./server/runtime/libs","-Dparallel.startup=true","-Dserver.runtime.path.name=server","-XX:+UseContainerSupport","-XX:InitialRAMPercentage=75.0","-XX:MaxRAMPercentage=75.0","-XX:MinRAMPercentage=75.0","-XX:SurvivorRatio=3","-XX:NewRatio=1","-XX:-DisableExplicitGC","-XX:+PrintFlagsFinal","-XX:+PrintGC","-XX:+PrintGCDateStamps","-XX:+PrintGCDetails","-XX:+PrintGCTimeStamps","-Xloggc:/app/dump/gclog","-XX:+HeapDumpOnOutOfMemoryError","-XX:HeapDumpPath=/app/dump","-jar","./server/runtime/caf-bootstrap.jar","--spring.config.location=./server/runtime/"]
resources:
limits:
cpu: 6
memory: 28Gi
requests:
cpu: 6
memory: 28Gi
---
apiVersion: v1
kind: Service
metadata:
labels:
app: myapp
name: myapp-service
namespace: default
spec:
sessionAffinity: ClientIP
ports:
- port: 80
name: myapp-service
protocol: TCP
targetPort: 5200
selector:
app: myapp
type: NodePort