jdk1.8限制内存参数

阿里云1000元通用代金券点此领取

centos7上java应用使用 java -jar -Xms512m -Xmx512m 参数启动,限制不了内存,很快就会超过512m这个数,而且
还在不停的增长,大概在1.7G就会停止

增加各种参数-Xms512m -Xmx512m -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=200m -XX:MaxDirectMemorySize=128m -Xss256K -XX:+DisableExplicitGC -XX:SurvivorRatio=3 -XX:+UseAdaptiveSizePolicy -XX:ParallelGCThreads=2 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128M -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly都没有办法限制

从prometheus监控上看,heap,noheap内存加起来占用只有500M

安装jprofilter工具查看,有一个Compressed class space空间,占了1G

结果jdk1.8默认就打开了-XX:+UseCompressedClassPointers 这个参数,并且设置为1G。这个内存大小可通过-XX:CompressedClassSpaceSize参数来控制

参数作用是设置Klass Metaspace的大小,默认1G

Klass Metaspace就是用来存klass的,klass是class文件在jvm里的运行时数据结构,没有开启压缩指针,就不会有-XX:CompressedClassSpaceSize=1g这块内存,但是jdk1.8里应该是默认开启的。并且,如果这块内存会如果没有满会一直增加。

将启动参数改为java -jar -server -Xms512m -Xmx512m -XX:CompressedClassSpaceSize=128m -XX:MetaspaceSize=200m -XX:MaxMetaspaceSize=200m ,最终内存大小稳定在700多M,这里是512m+128m,没有再次出现持续上涨的情况

### JDK 1.8 中 JVM 的内存模型详解 JDK 1.8 对 JVM 内存模型进行了重要调整,特别是针对方法区的设计。以下是 JDK 1.8 中 JVM 内存模型的主要组成部分及其功能描述: #### 1. **程序计数器 (Program Counter Register)** 程序计数器是一块较小的内存区域,用于记录当前线程所执行的字节码指令的位置。每条线程都有独立的程序计数器,互不影响。 #### 2. **Java 虚拟机栈 (Java Virtual Machine Stacks)** 虚拟机栈是线程私有的,生命周期与线程相同。每个方法在执行时都会创建一个栈帧(Stack Frame),用于存储局部变量表、操作数栈、动态链接、返回地址等信息。如果线程请求的栈深度大于允许的最大深度,则会抛出 `StackOverflowError`;如果虚拟机栈可以动态扩展,而扩展失败则会抛出 `OutOfMemoryError`[^4]。 #### 3. **本地方法栈 (Native Method Stack)** 本地方法栈类似于 Java 虚拟机栈,但它服务于 Native 方法。同样地,如果栈深度超过最大限制,可能会抛出 `StackOverflowError` 或 `OutOfMemoryError`。 #### 4. **Java 堆 (Heap)** Java 堆是 JVM 所管理的内存中最大的一块,被所有线程共享。它是垃圾收集器(GC)管理的主要区域,几乎所有的对象实例都在这里分配。堆的空间大小可以通过 `-Xmx` 和 `-Xms` 参数设置。如果堆中的可用内存不足以分配新对象,并且堆无法进一步扩展,则会抛出 `OutOfMemoryError` 异常[^5]。 #### 5. **方法区 (Method Area)** 方法区是一个线程共享的内存区域,主要用于存储已被虚拟机加载的类信息、常量、静态变量以及即时编译后的代码缓存等数据。在 JDK 1.8 及之后版本中,方法区的概念由元空间(MetaSpace)实现,不再依赖于永久代(Permanent Generation)。 - **元空间的特点**: - 元空间位于本地内存(Native Memory)中,而非 JVM 的堆中。 - 它的大小受操作系统本身的内存限制影响,而不是通过 JVM 参数严格限定。 - 如果物理内存不足或者元空间耗尽,仍然可能抛出 `OutOfMemoryError` 异常。 #### 6. **运行时常量池 (Runtime Constant Pool)** 运行时常量池是方法区的一部分,用于存储编译期生成的各种字面量和符号引用。这些内容会在类加载后进入方法区的运行时常量池。由于运行时常量池属于方法区的一部分,因此它的容量也受到方法区配置的影响。如果常量池过大导致方法区内存不足,也可能引发 `OutOfMemoryError`。 --- ### 示例代码:触发 OutOfMemoryError 以下代码展示了如何通过不断创建字符串对象来模拟 `OutOfMemoryError` 错误场景: ```java public class OOMExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } } } ``` 上述代码中,`String.intern()` 将字符串加入到运行时常量池中,可能导致方法区或元空间耗尽从而抛出异常。 --- ####
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值