Java方法区的理解
- 方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。
- 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开
- 所以方法区看作是一块独立于Java堆的内存空间
基本理解
- 方法区(Method Area) 与Java堆一样,是各个线程共享的内存区域.
- 方法区在JVM启动的时候被创建,并且它的实际的物理内存空间中和Java堆区一样都可以是不连续的.
- 方法区的大小,跟堆空间一样,可以选择固定大小或者可拓展.
- 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:
java.lang.OutOfMemoryError: PermGen space
(1.8以前)或者java.lang.OutOfMemoryError: Metaspace
(1.8及以后)- 加载大量的第三方的Jar包;Tomcat部署的工程过多(30-50个);大量动态的生成反射类
- 关闭JVM就会释放这个区域的内存
方法区大小设置
- 1.8及以后
- 设置初始值
-XX:MetaspaceSize=100m
- 设置最大值
-XX:MaxMetaspaceSize=100m
(默认值是-1,表示没有限制)
- 设置初始值
方法区内部结构
方法区存储什么?
方法区 它用于存储已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等
类型信息
对每个加载的类型(class,interface,enum,annotation),JVM必须在方法区中存储以下类型信息:
- 这个类型的完整有效名称(全名=包名.类名)
- 这个类型直接父类的完整有效名
- 这个类型的修饰符(public , abstract , final的某个子集)
- 这个类型直接接口的一个有序列表
域(Field)信息
- JVM必须在方法区中保存类型的所有域的相关信息以及域的声明顺序
- 域的相关信息包括:域名称,域类型,域修饰符
方法(Method)信息
JVM必须保存所有方法的以下信息,同域信息一样包括声明顺序
- 方法名称
- 方法的返回类型
- 方法参数的数量和类型
- 方法的修饰符
- 方法的字节码,操作数栈,局部变量表及大小(abstract和native方法除外)
- 异常表
- 每个异常处理的开始位置,结束位置,代码处理在程序计数器中的偏移地址,被捕获的异常类的常量池索引
non-final的类变量
- 静态变量和类关联在一起,随着类的加载而加载,他们成为类数据在逻辑上的一部分
- 类变量被类的所有实例共享,即使没有类实例时你也可以访问它
全局常量:static final
被声明为final的类变量的处理方法则不同,每个全局常量在编译的时候就会被分配
常量池与运行时常量池
常量池:
- 一个有效的字节码文件中除了包含类的版本信息,字段,方法以及接口等描述信息外,还包含一项信息那就是常量池表,包括各种字面量和对类型,域和方法的符号引用
简单来说,常量池可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等类型
运行时常量池:
- 运行时常量池是方法区的一部分
- 常量池表是class文件的一部分,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后放到方法区的运行时常量池中.
- 在加载类和接口到虚拟机后,就会创建对应的运行时常量池
- JVM为每个已加载的类型都维护一个常量池.池中的数据像数组项一样,是通过索引访问
- 运行时常量池相对于Class文件常量池的另一重要特征是:具备动态性
方法区在jdk678的演变过程
jdk6:
方法区是个概念,具体实现是通过永久代来实现
jdk7:
将静态变量和StringTable放到了堆空间中
jdk8:
方法区的实现由元空间实现,存储在本地内存上,不在占用虚拟机内存.
为什么要用元空间替换永久代?
为永久代设置空间大小很难确定
在某些场景下,如果动态加载类过多,容易产生Perm区的OOM.比如某个实际Web工程中,因为功能点比较多,在运行过程中,要不断动态加载很多类,经常出现致命错误
对永久代进行调优很困难
为什么要将StringTable调整到堆空间中?
jdk7中将StringTable放到了堆空间中,因为永久代的回收效率很低,在full gc的时候才会触发.而full gc是老年代的空间不足,永久代不足时才会触发.
这就导致了StringTable回收效率不高.而我们开发中会有大量的字符串被创建,回收效率低,导致永久代内存不足,放到堆里,能及时回收内存
Java方法区的理解的更多相关文章
- (4)java方法区
java方法区[名词解析] --->和java堆一样,方法区是一块所有线程共享的内存区域. --->保存系统的类信息,比如,类的字段,方法,常量池等. ...
- 【JVM】java方法区
java方法区[名词解析] --->和java堆一样,方法区是一块所有线程共享的内存区域. --->保存系统的类信息,比如,类的字段,方法,常量池等. ...
- Java方法区和永久代
Java方法区和永久代 目前有三大Java虚拟机:HotSpot,oracle JRockit,IBM J9. JRockit是oracle发明的,用于其WebLogic服务器,IBM JVM是IBM ...
- Java 字符串常量存放在堆内存还是JAVA方法区?
JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池. JDK1.8开始,取消了Java方法区,取而代之的是位于直接内 ...
- Java方法区和运行时常量池溢出问题分析
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
- Java方法区和运行时常量池溢出问题分析(转)
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
- 对JVM虚拟机中方法区的理解
因为jdk8的jvm已经取消了方法区,所以这边先主要介绍jdk8以下版本中方法区相关内容. 1.虚拟机规范中方法区的概念: 原文链接:http://docs.oracle.com/javase/spe ...
- Java方法区(Method Area)
方法区与Java堆一样,是各个线程共享的内存区域,他在与存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,虽然Java虚拟机规范把方法区描述为堆得一个逻辑部分,但是他却有一个别 ...
- Java方法区
方法区 在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内 ...
随机推荐
- .NET Core 环境变量详解
一.概述 软件从开发到正式上线,在这个过程中我们会分为多个阶段,通常会有开发.测试.以及上线等.每个阶段对应的环境参数配置我们会使用不同的参数.比如数据库的连接字符串,开发环境一般我们都是连接的测试库 ...
- [题解] [NOI Online 2021 入门组 T3] 重力球
题目大意 在一个 \(n\times n\) 的矩形中,题目会给出 \(m\) 个障碍物.有两个小球,你可以选定四个方向(上下左右)的其中一个,小球会朝着这四个方向一直滚动,直到遇到障碍物或是矩形的边 ...
- Androi Studio 之 RelativeLayout
RelativeLayout简介 •基本属性 •根据父容器定位 •父容器定位属性示意图 •根据兄弟组件定位 •根据兄弟组件定位 •margin(偏移) •padding(填充) •margin与pad ...
- 亲自动手实现Python+pygame中国象棋游戏
功能1:实现游戏整体界面显示 一.创建基本的结构 代码如下: import time import pygame def main(): # 初始化pygame pygame.init() # 创建用 ...
- (原创)高DPI适配经验系列:(二)按DPI范围适配
一.前言 一个软件,往往会用到位图资源,比如图标.图片.水晶按钮等. 在使用了位图资源后,就不能对任意DPI都进行适配,因为这样适配的代价太大了. 像Win10的缩放比例可以由100%-500%,如果 ...
- Chrome89针对sessionStorage的更新导致数据共享问题
最近将chrome更新到最新的版本,然后发现以前可以正常使用的功能无法使用了,经过分析后发现是浏览器新版本才出现的问题,今天记录以下. 一.遇到的问题 我们具体的问题场景,在A页面中需要打开B页面,同 ...
- 【oracle学习笔记01】oracle architecture —— Memory Strucrure
附图3: granule_size for each components 附图4:
- CSS 常用样式 – 背景属性
一.背景颜色 background-color 属性名:background-color 作用:在盒子区域添加背景颜色的修饰 加载区域:在 border 及以内加载背景颜色 属性值:颜色名.颜色值 & ...
- 两种纯CSS方式实现hover图片pop-out弹出效果
实现原理 主要图形的组成元素由背景和前景图两个元素,以下示例代码中,背景元素使用伪元素 figure::before 表示, 前景元素使用 figure img 表示,当鼠标 hover 悬浮至 fi ...
- shell脚本 5 sed和awk
文本处理三剑客 在 Shell 下使用这些正则表达式处理文本最多的命令有下面几个工具: 命令 描述 grep 默认不支持扩展表达式,加-E 选项开启 ERE.如果不加-E 使用花括号要加转义符\{\} ...