java虚拟机jvm方法区实例讲解
和java堆一样,方法区是一块所有线程共享的内存区域,用于保存系统的类信息,类的信息有哪些呢。字段、方法、常量池。方法区也有一块内存区域所以方法区的内存大小,决定了系统可以包含多少个类,如果系统类太多,方法区内存不够肯定会导致方法区溢出,虚拟机同样会抛出内存溢出信息。(内存溢出后面相关文章给大家总结)
jdk6和jdk7中,方法区可以理解为永久区(perm).永久区可以使用参数-xx:permsize和-xx:maxpermsize制定。默认情况下-xx:maxpermsize为64mb.如果你项目中使用代理模式或者cglib的话可能在运行的时候生成大量的类,如果这样,需要设置一下永久区的大小,防止永久区内存溢出。
cglib会在后面专门的章节和代理模式一起讲解。(这个系列专注的是jvm的讲解)
使用下面代码:
for (int i = 0; i <10000; i++) { cglibwapper c=new cglibwapper("cn.springok.perm"+i) }
代码解释:会根据传入的参数动态生成一个类以及类的实例。因为对象实例化,类的字段、方法、常量池保存在方法区,因此操作会占用一定内存的。
大量的类可能导致方法区溢出,使用下面的参数运行代码:
-xx:permsize=10m -xx:maxpermsize=10m -xx:printgcdetails
参数说明:
- -xx:permsize=10m 初始永久区大小10m
- -xx:maxpermsize 方法区最大内存10m。
- -xx:printgcdetails 打印日志详情。
执行程序部分输出如下:
compacting perm gen total 86272k, used 86136k [0x44600000, 0x49a40000, 0x64600000)
the space 86272k, 99% used [0x44600000, 0x49a1e2f8, 0x49a1e400, 0x49a40000)
系统内存溢出了,扩大-xx:maxpermsize值,可以生成更多的类。
可以使用工具visual vm观察方法区的具体使用情况。
需要注意一点:
jdk8中永久区被移除了,取而代之的是元数据区,可能方法区依赖jvm的内存吧。元数据区可以使用-xx:maxmetaspacesize制定,跟之前版本的-xx:maxpermsize一样,分配的值越多,就可以支持更多的类。不同的是元数据区是堆外直接内存,与方法永久区不同,在不指定大小的情况下,虚拟机会耗尽所有可用的系统内存。
元数据区发生溢出,虚拟机一样抛出异常,如下:
java.lang.outofmemoryerror metaspace
到此这篇关于java虚拟机jvm方法区实例讲解的文章就介绍到这了,更多相关java虚拟机 jvm 方法区实战内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
推荐阅读
-
Java高级之虚拟机加载机制的实例讲解
-
Java窗体居中显示的2种方法(实例讲解)
-
【JVM学习】2.Java虚拟机运行时数据区
-
java虚拟机jvm方法区实例讲解
-
java虚拟机栈中,一个对象变量、方法等对应在jvm运行时数据区中的位置
-
java jvm两种存储区的类型知识点讲解
-
OOM实战:堆内存溢出 虚拟机栈和本地方法栈溢出 jvm栈容量太小 栈帧太大 栈太小,导致线程分配少,创建更多的线程将导致oom 方法区和运行时常量池溢出
-
jvm深度学习(3):java方法的运行与虚拟机栈
-
简单介绍java中堆区、方法区和栈区的代码实例
-
[二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义