对JVM虚拟机中方法区的理解
因为jdk8的jvm已经取消了方法区,所以这边先主要介绍jdk8以下版本中方法区相关内容。
1.虚拟机规范中方法区的概念:
原文链接:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5.4
The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process.
It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization.
翻译:JVM有一个所有线程共享的方法区。方法区类似于一个常规编程语言编译后代码的存储区域,或者操作系统进程中的代码段。它存储每个类的结构,比如运行时常量池,字段和方法数据,以及方法和构造体的代码,包括在类和实例初始化、接口初始化过程中用到的特殊方法(比如:<init>,<clinit>等,可参考原文链接) The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This version of the Java Virtual Machine specification does not mandate the location of the method area or the policies used to manage compiled code. The method area may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger method area becomes unnecessary. The memory for the method area does not need to be contiguous.
翻译:方法区在虚拟机启动时创建。尽管方法区在逻辑上是堆的一部分,JVM的简单实现也许选择既不进行垃圾收集,也不进行整理。这个版本的虚拟机规范不强制方法区的位置以及用来管理编译后代码的策略。方法区可能固定大小,也可能按计算需要进行扩展以及当更大的方法区变得没必要时进行收缩。方法区的内存不需要是连续的。
A Java Virtual Machine implementation may provide the programmer or the user control over the initial size of the method area, as well as, in the case of a varying-size method area, control over the maximum and minimum method area size.
JVM实现可能提供给程序员或者用户对方法区初始大小的控制,以及,在可变容量情况下,对最大和最小容量的控制。
The following exceptional condition is associated with the method area: If memory in the method area cannot be made available to satisfy an allocation request, the Java Virtual Machine throws an OutOfMemoryError.
与方法区关联的异常情况:
如果方法区的内存不能满足一次分配内存的请求,虚拟机抛出OOM错误。
大概能了解到:
方法区主要用于存放Class相关的信息,如运行时常量池,字段和方法数据,以及方法和构造体的代码,包括在类和实例初始化、接口初始化过程中用到的特殊方法(比如:<init>,<clinit>等)。
2.java虚拟机:JVM高级特性与最佳实践中的定义:
方法区( Method Area) 与Java堆一样, 是各个线程共享的内存区域, 它用于存储已被虚拟机加载的类信息、
常量、 静态变量、 即时编译器编译后的代码等数据。 虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分, 但是
它却有一个别名叫做Non-Heap( 非堆) , 目的应该是与Java堆区分开来。
对于习惯在HotSpot虚拟机上开发、 部署程序的开发者来说, 很多人都更愿意把方法区称为“ 永久
代” ( Permanent Generation) , 本质上两者并不等价, 仅仅是因为HotSpot虚拟机的设计团队选择把GC分代收集
扩展至方法区, 或者说使用永久代来实现方法区而已, 这样HotSpot的垃圾收集器可以像管理Java堆一样管理这部
分内存, 能够省去专门为方法区编写内存管理代码的工作。 对于其他虚拟机( 如BEA JRockit、 IBM J9等) 来说是
不存在永久代的概念的。 原则上, 如何实现方法区属于虚拟机实现细节, 不受虚拟机规范约束, 但使用永久代来实
现方法区, 现在看来并不是一个好主意, 因为这样更容易遇到内存溢出问题( 永久代有-XX: MaxPermSize的上
限, J9和JRockit只要没有触碰到进程可用内存的上限, 例如32位系统中的4GB, 就不会出现问题) , 而且有极少数
方法( 例如String.intern( ) ) 会因这个原因导致不同虚拟机下有不同的表现。 因此, 对于HotSpot虚拟机, 根据
官方发布的路线图信息, 现在也有放弃永久代并逐步改为采用Native Memory来实现方法区的规划了[1], 在目前已
经发布的JDK 1.7的HotSpot中, 已经把原本放在永久代的字符串常量池移出。
Java虚拟机规范对方法区的限制非常宽松, 除了和Java堆一样不需要连续的内存和可以选择固定大小或者可扩
展外, 还可以选择不实现垃圾收集。 相对而言, 垃圾收集行为在这个区域是比较少出现的, 但并非数据进入了方法
区就如永久代的名字一样“ 永久” 存在了。 这区域的内存回收目标主要是针对常量池的回收和对类型的卸载, 一般
来说, 这个区域的回收“ 成绩” 比较难以令人满意, 尤其是类型的卸载, 条件相当苛刻, 但是这部分区域的回收确
实是必要的。 在Sun公司的BUG列表中, 曾出现过的若干个严重的BUG就是由于低版本的HotSpot虚拟机对此区域未完
全回收而导致内存泄漏。
根据Java虚拟机规范的规定, 当方法区无法满足内存分配需求时, 将抛出OutOfMemoryError异常
3.永久代和方法区的关系
永久代常常不和方法区一在同一个层面来提起,和它并列的词语一般是:新生代和老年代。
提到新生代(因为通常采用标记-复制算法,常又分为Eden和两个Survivor)、老年代、永久代,我们一般想到的是分代收集的垃圾收集算法。
比如新生代常用标记-复制算法,老年代常用标记-清理或者标记-整理,而永久代呢,是HotSpot虚拟机实现方法区的地方。
这个区域(方法区),在虚拟机规范中,是不要求有垃圾收集的,只是HotSpot虚拟机仍然对方法区所处的永久代进行了垃圾回收,
主要是无用的字符常量或者Class信息,虽然这部分数据进行回收的条件很苛刻,不过还是有的。
具体也可以参考下面的链接:
https://www.zhihu.com/question/49044988
对JVM虚拟机中方法区的理解的更多相关文章
- 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法
		
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...
 - [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义
		
前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine ,既然是虚拟机, ...
 - Java 底层机制(JVM/堆/栈/方法区/GC/类加载)
		
转载:https://www.jianshu.com/p/ae97b692614e?from=timeline JVM体系结构 JVM是一种解释执行class文件的规范技术. JVM体系结构 我翻 ...
 - Java方法区的理解
		
方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩. 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开 所以方法区看作是一块 ...
 - 【JVM】java方法区
		
java方法区[名词解析] --->和java堆一样,方法区是一块所有线程共享的内存区域. --->保存系统的类信息,比如,类的字段,方法,常量池等. ...
 - JVM运行时数据区--深入理解Java虚拟机 读后感
		
程序计数器 程序计数器是线程私有的区域,很好理解嘛~,每个线程当然得有个计数器记录当前执行到那个指令.占用的内存空间小,可以把它看成是当前线程所执行的字节码的行号指示器.如果线程在执行Java方法,这 ...
 - java虚拟机 jvm java堆 方法区 java栈
		
java堆是java应用程序最密切的内存空间.几乎所有的对象都存在堆中.java堆完全自动化管理,通过垃圾回收机制,垃圾对象会自动清理,不需要显式释放. 根据java垃圾回收机制的不同,java堆可能 ...
 - JVM堆 栈 方法区详解
		
一.栈 每当启用一个线程时,JVM就为他分配一个JAVA栈,栈是以帧为单位保存当前线程的运行状态 栈是由栈帧组成,每当线程调用一个java方法时,JVM就会在该线程对应的栈中压入一个帧 只有在调用一个 ...
 - java在jvm虚拟机中是如何实现多态的?
		
原文地址:https://blog.csdn.net/huangrunqing/article/details/51996424 众所周知,多态是面向对象编程语言的重要特性,它允许基类的指针或引用指向 ...
 
随机推荐
- python中的return的返回与执行
			
author:headsen chen date:2018-03-21 15:12:09 notice:created by headsen chen himself and not allo ...
 - 前端dom元素的操作优化建议
			
参考自:http://blog.csdn.net/xuexiaodong009/article/details/51810252 其实在web开发中,单纯因为js导致性能问题的很少,主要都是因为DOM ...
 - Redis 中的数据类型及基本操作
			
Redis 内置的数据类型有 5种:字符串String.哈希Hash.列表List.集合Set.有序集合ZSet 字符串类型 String 是 Redis 中最基本的类型,一个 key 对应着一个 v ...
 - swift 相关小随笔
			
关键词 typealias 对已经存在的类重命名 let 修饰不可变值 var 修饰可变的值 lazy 懒加载修饰符,用到的时候才会加载 convenience 原方法的备用方法,方法一致,但是 ...
 - id 选择器
			
id 选择器 1.id 选择器可以为标有特定 id 的 HTML 元素指定特定的样式. (即也可以说,可以将已经预先定义的特定样式,通过id选择器,赋值指向HTML 元素) 2.HTML元素以id属性 ...
 - 福州大学W班-助教总结
			
开学初对自己的期望 在即将到来的学期前,我希望我可以做到以下几点: 1.多参与同学的课程设计,并提出自己的见解 2.不断提高个人的专业技能,活到老学到老 3.能够及时对同学的博客进行评论,并给出有用的 ...
 - Java作业-网络编程
			
Java网络编程 关于结合以前的大作业(即我的图书馆管理系统) 我感觉,图书馆管理系统更像是一个偏向于B/S模式的体系,如果想让他可用性变得更好,可以优化的地方只有使用数据库来代替文件,我个人是没有想 ...
 - 冲刺NO.12
			
Alpha冲刺第十二天 站立式会议 项目进展 项目核心功能,如学生基本信息管理模块,学生信用信息模块,奖惩事务管理模块等等都已完成,测试工作大体结束. 问题困难 项目结束后对项目的阶段性总结缺乏一定的 ...
 - win7 Anaconda 安装 scrapy模块
			
之前用了很多方法,都安装不成功,今天终于成功了..说下方法.. anaconda的清华镜像:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ ...
 - Node入门教程(7)第五章:node 模块化(下) npm与yarn详解
			
Node的包管理器 JavaScript缺少包结构的定义,而CommonJS定义了一系列的规范.而NPM的出现则是为了在CommonJS规范的基础上,实现解决包的安装卸载,依赖管理,版本管理等问题. ...