对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创建容器和集合之源码分析
_collections_abc.py文件中提供了许多抽象基类,这些类将集合分解成许多互相独立的属性集 __all__ = ["Awaitable", "Coroutin ...
- 分享python分析wave, pcm音频文件
最近研究的,我用的是python3.3, 用matplotlib画图, 下面代码演示分析pcm文件,如果是wave文件,把wave的文件头去掉就是pcm文件了. 代码如下 # -*- coding:u ...
- 列表生成式、生成器&迭代器
一.列表生成式 先有列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,怎么实现? 方法一: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, ...
- 用three.js创建一个简易的天空盒
本文创建的天空盒是用六张图片来创建的.笔者会论述两种方法来创建,都是最简单基本的方法,不涉及着色器的使用.一种是创建一个盒子,然后将图片作为盒子6个面的纹理贴上来创建.另一种则是简单的将纹理作为场景的 ...
- vuex入门
安装&使用 npm install vuex --save 1 通过Vue.use()来使用: import Vue from 'vue' import Vuex from 'vuex' Vu ...
- [POJ1050] To the Max 及最大子段和与最大矩阵和的求解方法
最大子段和 Ο(n) 的时间求出价值最大的子段 #include<cstdio> #include<iostream> using namespace std; int n,m ...
- 使用了旧版nuget的.net项目在git中的问题
曾几何时,使用nuget包管理项目依赖还需要将nuget执行程序及其配置文件包含在项目中. 如上图所示,在解决方案文件夹中,有专门为nuget程序设置的 .nuget 子目录. 当将项目纳入git管理 ...
- C# Int 类型线程不安全
之前统计报表算法做了一个优化,一个查询二十分钟导致客户端超时,优化到只需要5秒钟.后来发现for循环里数据合并的时候耗时,就用并行做优化.但是发现并行后丢居然数据(当然是因为List线程不安全). 前 ...
- 《UNIX网络编程 卷1:套接字联网API》读书笔记(一):网络编程简介
概述 要编写通过计算机网络通信的程序,首先要确定这些程序相互通信所用的协议.大多数网络是按照划分成客户和服务器来组织的.本章及后续章节的焦点是TCP/IP协议族,也可称为网际协议族.下图为客户与服务器 ...
- Matlab绘图基础——绘制三维曲线
%% 绘制三维曲线 %plot3函数,其中每一组x,y,z组成一组曲线的坐标参数,选项的定义和plot函数相同. %1.当x,y,z是同维向量时,则x,y,z 对应元素构成一条三维曲线. x0 = 0 ...