JAVA ulimit_如何正确使用ulimit与java?

实际上很难有效地限制java.许多池都是无限制的,当分配尝试失败时,JVM会发生灾难性故障.并非所有内存都是实际提交的,但其中大部分都是保留的,因此计入ulimit强加的虚拟内存限制.

经过大量调查,我发现了许多不同类型的内存java使用.此答案适用于64位系统上的OpenJDK和Oracle 8.x:

这是JVM内存中最容易理解的部分.它是使用大部分程序存储器的地方.它可以使用-Xmx和-Xms选项进行控制.

元空间

这似乎包含有关已加载的类的元数据.我无法确定这个类别是否会向操作系统释放内存,或者它是否只会增长.默认最大值似乎为1g.它可以使用-XX:MaxMetaspaceSize选项进行控制.注意:如果不指定Compressed类空间,指定它可能不会执行任何操作.

压缩类空间

这似乎与Metaspace有关.我无法确定这个类别是否会向操作系统释放内存,或者它是否只会增长.默认最大值似乎为1g.它可以使用’-XX:CompressedClassSpaceSize`选项进行控制.

垃圾收集器开销

根据所选的垃圾收集器,似乎存在固定的开销量,以及基于堆大小的额外分配.观察表明,此开销约为堆大小的5%.没有已知的限制此选项(除了选择不同的GC算法).

主题

每个线程为其堆栈预留1米. JVM似乎预留了额外的50米内存作为防止堆栈溢出的安全措施.可以使用-Xss选项控制堆栈大小.安全尺寸无法控制.由于无法强制执行最大线程数,并且每个线程都需要一定量的内存,因此这个内存池在技术上是无限制的.

Jar文件(和zip文件)

默认的zip实现将使用内存映射来进行zip文件访问.这意味着访问的每个jar和zip文件都将被内存映射(需要一定量的保留内存等于文件大小的总和).可以通过设置sun.zip.disableMemoryMapping系统属性来禁用此行为(如-Dsun.zip.disableMemoryMapping = true)

NIO Direct Buffers

任何直接缓冲区(使用allocateDirect创建)都将使用该堆的堆外内存.最好的NIO性能带有直接缓冲区,因此很多框架都会使用它们.

JVM无法限制NIO缓冲区允许的总内存量,因此该池在技术上是无限制的.

此外,对于接触缓冲区的每个线程,此内存在堆上重复.有关详细信息,请参见this.

库分配的本机内存

如果您使用的是任何本机库,则它们分配的任何内存都将在堆外.一些核心java库(如java.util.zip.ZipFile)也使用消耗堆内存的本机库.

JVM无法限制本机库分配的内存总量,因此该池在技术上是无限制的.

malloc竞技场

JVM对许多这些本机内存请求使用malloc.为避免线程争用问题,malloc函数使用多个预分配池.默认池数等于8 x cpu,但可以通过设置环境变量MALLOC_ARENAS_MAX来覆盖它.即使不是全部使用,每个池也会保留一定量的内存.

对于java,通常建议将MALLOC_ARENAS_MAX设置为1-4,因为最常见的分配是从堆完成的,较低的竞技场计数将防止浪费的虚拟内存向ulimit计数.

此类别在技术上不是它自己的池,但它解释了额外内存的虚拟分配.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值