前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JVM - 参数配置影响线程数

JVM - 参数配置影响线程数

作者头像
用户2987604
发布2020-06-15 15:35:00
4.9K1
发布2020-06-15 15:35:00
举报

一、题目相关参数

1.1 三个重要参数

  • -Xms 为 jvm 启动时分配 Heap初始内存(最小内存),比如 -Xms200m,表示分配200M
  • -Xmx 为 jvm 运行过程中分配 Heap最大内存,比如 -Xms500m,表示jvm进程最多只能够占用500M内存
  • -Xss 为 jvm 启动的每个线程分配的内存大小(stack size),默认JDK1.4中是256K,JDK1.5+中是1M

通常, -Xms-Xmx 设置成一样的,避免每次垃圾回收完成后JVM重新分配内存。因为当Heap不够用时,发生内存抖动,影响程序运行稳定性。

1.2 线程数的变动

准确来说,是 jvm 可生产线程数的数量,由三个方面影响:

  • jvm 的堆内存大小
  • Thread 的 Stack内存大小
  • 系统最大可创建的线程数量

增大堆内存(-Xms,-Xmx)会减少可创建的线程数量;增大线程栈内存(-Xss,32 位系统中此参数值最小为 60 K)也会减少可创建的线程数量。因此题中, -Xmx 加大,Heap内存增大,jvm 空闲的内存数(java虚拟机栈等)就更少,那么可以创建的线程也就更少。

系统从以下几个方面影响最大线程数:

  • /proc/sys/kernel/pid_max,
  • /proc/sys/kernel/thread-max,
  • maxuserprocess(ulimit -u),
  • /proc/sys/vm/maxmapcount

具体影响过程参考 https://blog.csdn.net/moonpure/article/details/80701878

1.3 三个内存方法

java.lang.Runtime 类中的 freeMemory(), totalMemory(), maxMemory() 这几个方法反映的都是 java 这个进程的内存情况,跟操作系统的内存根本没有关系。

maxMemory()

返回的是java虚拟机(这个进程)能够从操作系统那里挖到的最大的内存,以字节为单位,如果在运行 java 程序的时候,没有添加 -Xmx 参数,那么就是 64 M,也就是说 maxMemory() 返回的大约是6410241024 字节,这是 java 虚拟机默认情况下能从操作系统那里挖到的最大的内存。如果添加了 -Xmx 参数,将以这个参数后面的值为准,例如 java-cp you_classpath-Xmx512myour_class,那么最大内存就是 51210241024 字节。

totalMemory()

返回的是 java 虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有内存。如果在运行 java 的时候没有添加 -Xms 参数,那么,在 java 程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直到挖到 maxMemory() 为止,所以totalMemory() 是慢慢增大的。如果用了 -Xms 参数,程序在启动的时候就会无条件的从操作系统中挖 -Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。

freeMemory()

刚才讲到如果在运行java的时候没有添加 -Xms 参数,那么,在 java 程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,但是 java 虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行 java 程序的时候使用了 -Xms,这个时候因为程序在启动的时候就会无条件的从操作系统中挖 -Xms 后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候 freeMemory() 可能会有些大。

二、常用参数

2.1 堆设置

  • -Xms:初始堆大小
  • -Xmx:最大堆大小
  • -XX:NewSize=n:设置年轻代大小
  • -XX:NewRatio=n:设置年轻代和年老代的比值。如:为3,表示年轻代与年老代比值为1:3,年轻代占整个年轻代年老代和的1/4
  • -XX:SurvivorRatio=n:年轻代中Eden区与两个Survivor区的比值。注意Survivor区有两个。如:3,表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5
  • -XX:MaxPermSize=n:设置持久代大小

JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。

代码语言:javascript
复制
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k-Xmx3550m # 设置JVM最大可用内存为3550M。-Xms3550m # 设置JVM促使内存为3550m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。-Xmn2g # 设置年轻代大小为2G。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小 。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。-Xss128k # 设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。

依据的原则是根据Java Performance里面的推荐公式来进行设置。

具体来讲:

  • Java整个堆大小设置,Xmx 和 Xms设置为老年代存活对象的3-4倍,即FullGC之后的老年代内存占用的3-4倍
  • 永久代 PermSize和MaxPermSize设置为老年代存活对象的1.2-1.5倍。
  • 年轻代Xmn的设置为老年代存活对象的1-1.5倍。
  • 老年代的内存大小设置为老年代存活对象的2-3倍。

BTW:

1、Sun官方建议年轻代的大小为整个堆的3/8左右, 所以按照上述设置的方式,基本符合Sun的建议。

2、堆大小=年轻代大小+年老代大小, 即 xmx=xmn+老年代大小 。Permsize不影响堆大小。

3、为什么要按照上面的来进行设置呢?没有具体的说明,但应该是根据多种调优之后得出的一个结论。

具体调整策略参考 https://blog.csdn.net/losetowin/article/details/78569001

2.2 收集器设置

  • -XX:+UseSerialGC :设置串行收集器
  • -XX:+UseParallelGC :设置并行收集器
  • -XX:+UseParalledlOldGC :设置并行年老代收集器
  • -XX:+UseConcMarkSweepGC :设置并发收集器

JVM给了三种选择:串行收集器、并行收集器、并发收集器 ,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数。JDK5.0 以后,JVM会根据当前系统配置

吞吐量优先 的并行收集器

如上文所述,并行收集器主要以到达一定的吞吐量为目标,适用于科学技术和后台处理等。

典型配置 :

代码语言:javascript
复制
java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20-XX:+UseParallelGC # 选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。-XX:ParallelGCThreads=20 # 配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
响应时间优先 的并发收集器

如上文所述,并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。典型配置 :

代码语言:javascript
复制
java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC-XX:+UseConcMarkSweepGC # 设置年老代为并发收集。测试中配置这个以后,-XX:NewRatio=4的配置失效了,原因不明。所以,此时年轻代大小最好用-Xmn设置。-XX:+UseParNewGC # 设置年轻代为并行收集。可与CMS收集同时使用。JDK5.0以上,JVM会根据系统配置自行设置,所以无需再设置此值。

2.3 垃圾回收统计信息

-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:filename

2.4 并行收集器设置

-XX:ParallelGCThreads=n :设置并行收集器收集时使用的CPU数。并行收集线程数。-XX:MaxGCPauseMillis=n :设置并行收集最大暂停时间 -XX:GCTimeRatio=n :设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

2.5 并发收集器设置

-XX:+CMSIncrementalMode :设置为增量模式。适用于单CPU情况。-XX:ParallelGCThreads=n :设置并发收集器年轻代收集方式为并行收集时,使用的CPU数。并行收集线程数。

参考

https://www.cnblogs.com/ceshi2016/p/8447989.html

https://blog.csdn.net/moonpure/article/details/80701878

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 董亮亮的开发笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 三个重要参数
  • 1.2 线程数的变动
  • 1.3 三个内存方法
    • maxMemory()
      • totalMemory()
        • freeMemory()
        • 二、常用参数
          • 2.1 堆设置
            • 2.2 收集器设置
              • 吞吐量优先 的并行收集器
              • 响应时间优先 的并发收集器
            • 2.3 垃圾回收统计信息
              • 2.4 并行收集器设置
                • 2.5 并发收集器设置
                • 参考
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档