java默认启动堆大小 jdk默认堆大小_堆内存

 堆内存分配:
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64
JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。

 

JDK8+移除了Perm,引入了Metapsace

JDK 1.8 的对 JVM 架构的改造将类元数据放到本地内存中,另外,将常量池和静态变量放到 Java 堆里。HotSopt VM 将会为类的元数据明确分配和释放本地内存。在这种架构下,类元信息就突破了原来 -XX:MaxPermSize 的限制,现在可以使用更多的本地内存。这样就从一定程度上解决了原来在运行时生成大量类的造成经常 Full GC 问题,如运行时使用反射、代理等。

这个JVM参数是指Metaspace扩容时触发FullGC的初始化阈值,也是最小的阈值。这里有几个要点需要明确:

  1. 如果没有配置-XX:MetaspaceSize,那么触发FGC的阈值是21807104(约20.8m),可以通过jinfo -flag MetaspaceSize pid得到这个值;
  2. 如果配置了-XX:MetaspaceSize,那么触发FGC的阈值就是配置的值;
  3. Metaspace由于使用不断扩容到-XX:MetaspaceSize参数指定的量,就会发生FGC;且之后每次Metaspace扩容都可能会发生FGC(至于什么时候会,比较复杂,跟几个参数有关);
  4. 如果Old区配置CMS垃圾回收,那么扩容引起的FGC也会使用CMS算法进行回收;
  5. 如果MaxMetaspaceSize设置太小,可能会导致频繁FullGC,甚至OOM;

UnlockExperimentalVMOptions:

如果你想要的是jvm进程在容器中安全稳定的运行,不被容器kill,并且你的JDK版本小于10 你需要额外设置JVM参数-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap,即可保证你的Java进程不会因为内存问题被容器Kill。 当然这个方式使用起来简单,可靠,缺点也很明显,资源利用率过低(参考前面的表格MaxRAMFraction=4)。


-XX:+UseConcMarkSweepGC:设置年老代为并发收集。

+CMSParallelRemarkEnabled   减少Remark阶段暂停的时间,启用并行Remark,如果Remark阶段暂停时间长,可以启用这个参数

 

+UseCMSInitiatingOccupancyOnly 和CMSInitiatingOccupancyFraction=70 

参数指定CMS垃圾回收器在老年代达到80%的时候开始工作,如果不指定那么默认的值为92%


PrintCMSStatistics:

在 jvm 参数里添加-XX:PrintCMSStatistics=2(>0),通过 gc 日志可以看到 cms 回收器在 preclean 阶段执行的操作.

 

+PrintGCApplicationStoppedTime

打印垃圾回收期间程序暂停的时间.可与上面混合使用

 

+PrintGCDateStamps GC时间

 

 

-XX:+PrintHeapAtGC 打印GC前后的详细堆栈信息 

 

-Xloggc:/data/dubbo/logs/crm/innovation-ulove-cupid-provider/jvm.log:把相关日志信息记录到文件以便分析.
与上面几个配合使用

 

-XX:+HeapDumpOnOutOfMemoryError 参数表示当JVM发生OOM时,自动生成DUMP文件,

-XX:HeapDumpPath=/data/dubbo/logs/crm/innovation-ulove-cupid-provider参数表示生成DUMP文件的路径,也可以指定文件名称,例如:-XX:HeapDumpPath=${目录}/java_heapdump.hprof。如果不指定文件名,默认为:java_<pid>_<date>_<time>_heapDump.hprof。

 

-XX:ErrorFile=/data/dubbo/logs/crm/innovation-ulove-cupid-provider/hs_err_pid%p.log

当JVM发生致命错误导致崩溃时,会生成一个hs_err_pid_xxx.log这样的文件,该文件包含了导致 JVM crash 的重要信息,我们可以通过分析该文件定位到导致 JVM Crash 的原因,从而修复保证系统稳定。

 

 

 

-OmitStackTraceInFastThrow 

这是HotSpot VM专门针对异常做的一个优化,称为fast throw,当一些异常在代码里某个特定位置被抛出很多次的话,HotSpot Server Compiler(C2)会用fast throw来优化这个抛出异常的地方,直接抛出一个事先分配好的、类型匹配的对象,这个对象的message和stack trace都被清空。副作用:正好是需要知道哪里出问题的时候看不到stack trace了,不利于排查问题。

如果遇到没有stack trace的问题,可以考虑通过 -XX:-OmitStackTraceInFastThrow 禁用该默认的优化

 

 

 

 

 

 

 

-Xmn 618M:设置年轻代大小为618<。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
-Xss 512k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

 

再通过arthas看看jvm的一些信息:

java默认启动堆大小 jdk默认堆大小_堆栈_02

 

HotSpot,年轻代收集器是ParNew 老年代是cms

堆内存1.2G,年轻代和老年代各600

 

关于这一部分比较疑惑的的是 通过jinfo和-XX:+PrintCommandLineFlags -version看到的对的初始化和最大参数是不一样的:

 

 

java默认启动堆大小 jdk默认堆大小_堆栈_03

 根据jvm默认分配1/64和1/4给最小最大堆猜测,PrintCommandLineFlags是根据具体运行环境调整后的默认值,具体的运行环境如下:

 

java默认启动堆大小 jdk默认堆大小_JVM_04

 

每一个镜像我们分了2G的内存,按这个比例算下去应该是对的

======================================================

 

java默认启动堆大小 jdk默认堆大小_java默认启动堆大小_05

 

网站这边先来5g再说,垃圾回收器也不太一样

 

 

java默认启动堆大小 jdk默认堆大小_堆栈_06

 

 

 

java默认启动堆大小 jdk默认堆大小_java默认启动堆大小_07

 宿主机是65G,core-user也一样