JVM之方法区
方法区放什么
对于每一个加载的类型,会在方法区中保存以下信息:
- 类及其父类的全限定名(类的全路径名)(java.lang.Object没有父类)
- 类的类型(Class or Interface)
- 访问修饰符(public, abstract, final)
- 实现的接口的全限定名的列表
- 常量池
- 字段信息
- 方法信息
- 静态变量
- ClassLoader引用
- Class引用
对于每一个字段,会在方法区中保存以下信息(字段声明顺序也会保存):
- 字段名
- 字段的类型
- 字段的修饰符(public, private , protected, static, final, volatile, transient)
对于每一个方法,会在方法区中保存以下信息(方法声明顺序也会保存):
- 方法名
- 方法返回类型(或void)
- 参数信息
- 方法修饰符(public, private, protected , static, final, synchronized, native, abstract)
如果方法不是抽象方法并不是本地方法(Native Method),还会保存以下信息:
- 方法的字节码
- 本地变量表及操作数栈的大小
- 异常表
方法区注意的地方
- 默认64M
- 当OutOfMemoryError时,可以修改MaxPermSize
- 需要多大的永久代空间,取决于类的数量、方法的大小、常量池的大小
方法区的缺点
它的大小是在启动时固定好的,很难进行优化,-XX:MaxPermSize应该设置多大
方法区特点
- 方法区是线程安全的。由于所有的线程都共享方法区,所以,方法区里的数据访问必须被设计成线程安全的。例如,假如同时有两个线程都企图访问方法区中的同一个类,而这个类还没有被装入JVM,那么只允许一个线程去装载它,而其它线程必须等待
- 方法区的大小不必是固定的,JVM可根据应用需要动态调整。同时,方法区也不一定是连续的,方法区可以在一个堆(甚至是JVM自己的堆)中自由分配。
- 方法区也可被垃圾收集,当某个类不在被使用(不可触及)时,JVM将卸载这个类,进行垃圾收集
对方法区的另一种理解
方法区也是所有线程共享。主要用于存储类的信息、常量池、方法数据、方法代码等。方法区逻辑上属于堆的一部分,但是为了与堆进行区分,通常又叫“非堆”。 关于方法区内存溢出的问题会在下文中详细探讨。
永久代
JDK 1.6 还在使用永久代,当类或方法过多,就会导致永久代内存溢出。最典型的场景就是,在 jsp 页面比较多的情况,容易出现永久代内存溢出。
永久代的满了或者超过临界值,也会触发Full GC,而永久代也会被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。
代码
package com.paddx.test.memory;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
public class PermGenOomMock{
public static void main(String[] args) {
URL url = null;
List<ClassLoader> classLoaderList = new ArrayList<ClassLoader>();
try {
url = new File("/tmp").toURI().toURL();
URL[] urls = {url};
while (true){
ClassLoader loader = new URLClassLoader(urls);
classLoaderList.add(loader);
loader.loadClass("com.paddx.test.memory.Test");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
结果
永久代配置
PermSize
MaxPermSize
元空间
JDK1.8放弃了方法区,将其改成元空间,最大的区别是:元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。
内存溢出结果
元空间配置
-XX:MetaspaceSize
-XX:MaxMetaspaceSize
-XX:MinMetaspaceFreeRatio
相关推荐
学习 09 方法区, 记录方法区相关知识,重绘图示和 PPT。 文章包括栈、堆和方法区交互、方法区基本概念、方法区的演进、方法区的内部结构、方法区垃圾回收等相关内容。
自己总结的jvm中方法区的笔记,绘制了详细的思维导图,每个思维导图中均有详细的博文解释,方便大家学习和理解,免费分享给大家。适合jvm的爱好者和学习者
《JVM中方法区的深度解析》 方法区,作为Java虚拟机(JVM)内存模型的重要组成部分,是理解JVM工作原理的关键所在。本文将深入探讨方法区的定义、功能、与其它内存区域的关系,以及其在不同JVM版本中的演进,包括...
堆存储对象实例,方法区存放类信息,程序计数器记录当前线程执行的指令地址,虚拟机栈保存每个方法的局部变量、操作数栈等,本地方法栈为JNI调用的本地方法服务。 3. 指令集:JVM使用一套基于栈的指令集,这些指令...
在JDK8中,JVM内存结构发生了显著变化,尤其是元空间(MetaSpace)替代了永久代(Permanent Generation)作为方法区的一部分。这种方法区的调整是由于永久代存在的一些问题,比如大小设定困难,容易引发溢出,以及给...
JVM是Java Virtual Machine的缩写,它是Java平台的核心组件之一。它的主要任务是将编译后的Java类文件(.class文件)中的字节码转换为特定平台的机器码,实现了Java的“一次编写,到处运行”的跨平台特性。JVM由多个...
内存管理涉及JVM内存区域,包括堆、栈、方法区、程序计数器和本地方法栈,每部分都有其特定的用途和管理方式。 2. JVM内存模型:JVM内存模型定义了内存中各个部分的关系,以及在多线程环境下如何共享和分配内存。...
运行时数据区是 JVM 运行时的内存模型,它包括方法栈、PC 寄存器、本地方法栈、Java 堆、方法区和直接内存等部分。执行引擎负责读取运行时数据区的字节码,并逐个执行它们。 类加载器子系统是 JVM 的一个重要组成...
### Tomcat JVM内存设置方法详解 #### 一、前言 Tomcat作为一款广泛使用的Java应用服务器,其性能优化一直是开发者关注的重点之一。而在性能优化的过程中,合理设置JVM(Java Virtual Machine)内存是非常关键的一...
- **运行数据区**:包括堆、方法区、虚拟机栈、本地方法栈和程序计数器等几个部分。 - **堆**:存储对象实例,是所有线程共享的一块内存区域。 - **方法区**(在Java 8后变为元空间):存储已加载类的信息,如类...
2. **JVM内存结构**:主要包括堆、栈、方法区等,用于存储和管理数据。 3. **GC(Garbage Collection)算法**:自动内存管理机制,用于回收不再使用的对象所占用的内存空间。 4. **GC分析命令调优**:用于监控和优化...
2. **运行时数据区**:包括堆、方法区、程序计数器、虚拟机栈和本地方法栈。其中,堆是所有线程共享的内存区域,用于存储对象实例;方法区存储类信息;程序计数器记录当前线程执行的指令地址;虚拟机栈保存方法调用...
- **回收策略**:从JVM方法栈和本地方法栈引出来的引用开始,把每一个引出来的引用作为根依次搜索(遍历),如果从这个根开始寻找,找不到这个对象,那这个对象就是垃圾。 - **触发条件**:当对象不再被任何引用关联...
3. **方法区**:存储类信息、常量、静态变量等,也称为永久代,在现代JVM中通常被元空间(Metaspace)替代。 ### 垃圾收集(Garbage Collection) JVM自动进行内存清理,防止内存泄漏。垃圾收集器主要有串行、并行...
JVM在运行时,将内存空间分为若干个区域,主要包括方法区、堆内存、虚拟机栈、本地方法栈、程序计数器五个部分。 1. 方法区 方法区主要用于存储类信息、常量、静态变量等数据。在jdk1.7之前,方法区是堆的一个逻辑...
- 运行时常量池:方法区的一部分,存储编译期生成的各种字面量和符号引用。 4. **垃圾收集(GC)**: - 垃圾收集的目的是自动回收不再使用的对象所占用的内存。 - 分代收集理论:将堆分为新生代(Eden、Survivor...
3. **内存模型**:包括堆内存、栈内存、方法区(在Java 8之后变为元空间)、程序计数器、本地方法栈等,理解它们的作用有助于避免内存溢出和内存泄漏问题。 4. **垃圾收集**:JVM如何自动管理内存,理解不同垃圾...
静态属性在类加载时分配空间,存储在方法区(Method Area)中,这部分内存是所有类共享的。基本类型的静态属性直接存储值,而引用类型的静态属性存储的是对象在堆中的地址。静态属性可以通过类名直接访问,而无需...
- **Method Area(方法区)**:方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。在JDK 8之前,HotSpot虚拟机中的方法区被称为永久代(Permanent Generation)。随着JDK 8的发布,永久...
首先,JVM的内存结构分为堆、栈、方法区、程序计数器、本地方法栈等几个关键区域。堆是所有对象实例的存储区域,而栈则用于存储方法调用时的局部变量。方法区存储类信息、常量、静态变量等。程序计数器记录下一条要...