JVM06_方法区的概述、内部结构、演变、常量池、运行时常量池、垃圾回收(一)

简介: ①. 方法区的概述②. 方法区的内部结构

①. 方法区的概述


①. 方法区在JVM启动的时候被创建,并且它的实际的物理内存空间和Java堆区一样都可以是不连续的 | 关闭Jvm就会释放这个区域的内存


②. 方法区时逻辑上是堆的一个组成部分,但是在不同虚拟机里头实现是不一样的,最典型的就是永久代(PermGen space)和元空间(Metaspace)


(注意:方法区时一种规范,而永久代和元空间是它的一种实现方式)


③. 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误:(java.lang.OutOfMemoryError:PermGen space、java.lang.OutOfMemoryError:Metaspace)


  1. 加载大量的第三方的jar包


  1. tomcat部署的工程过多(30-50个)


  1. 大量动态的生成反射类


  • ④. 对于HotspotJVM而言,方法区还有一个别名叫非堆(Non-heap),目的就是要和堆分开,方法区可以看成一块独立于Java堆的内存空间


②. 方法区的内部结构


①. 深入理解Java虚拟机》书中对方法区存储内容描述如下:它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存


微信图片_20220106141622.png


②. 类型信息(对每个加载的类型(类class、接口interface、枚举enum、注解annotation),JVM必 .须在方法区中存储以下类型信息:


这个类型的完整有效名称(全名=包名.类名)


这个类型直接父类的完整有效名(对于interface或是java. lang.Object,都没有父类)


这个类型的修饰符(public, abstract, final的某个子集)


这个类型直接接口的一个有序列表


③. 域信息(成员变量)


JVM必须在方法区中保存类型的所有域的相关信息以及域的声明顺序。


域的相关信息包括:域名称、 域类型、域修饰符(public, private, protected, static, final, volatile, transient的某个子集)


④. 方法信息:JVM必须保存所有方法的以下信息,同域信息一样包括声明顺序

方法名称


方法的返回类型(或void)


方法参数的数量和类型(按顺序)


方法的修饰符(public, private, protected, static, final,synchronized, native , abstract的一个子集)


方法的字节码(bytecodes)、操作数栈、局部变量表及大小( abstract和native 方法除外)


异常表( abstract和native方法除外)


每个异常处理的开始位置、结束位置、代码处理在程序计数器中的偏移地址、被捕获的异常类的常量池索引


⑤. non-final的类变量


(Order.class字节码文件,右键Open in Teminal打开控制台,使用javap -v -p


Order.class > tst.txt 将字节码文件反编译并输出为txt文件,可以看到被声明为static final


的常量number在编译的时候就被赋值了,这不同于没有被final修饰的static变量count是


在类加载的准备阶段被赋值为默认的初始化值,在初始化的时候赋予正确的初始化值


 public static int count;
    descriptor: I
    flags: ACC_PUBLIC, ACC_STATIC
  public static final int number;
    descriptor: I
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
    ConstantValue: int 2


以下代码不会报空指针异常


public class MethodAreaTest {
    public static void main(String[] args) {
        Order order = null;
        order.hello();
        System.out.println(order.count);
    }
}
class Order {
    public static int count = 1;
    public static final int number = 2;
    public static void hello() {
        System.out.println("hello!");
    }
}


相关文章
|
21天前
|
算法 Java
JVM垃圾回收机制
JVM垃圾回收机制
15 0
|
11天前
|
存储 前端开发 安全
JVM内部世界(内存划分,类加载,垃圾回收)(上)
JVM内部世界(内存划分,类加载,垃圾回收)
44 0
|
15天前
|
存储 缓存 算法
深度解析JVM世界:垃圾判断和垃圾回收算法
深度解析JVM世界:垃圾判断和垃圾回收算法
|
30天前
|
Java Serverless 对象存储
Serverless 应用引擎常见问题之jvm在进行垃圾回收的时候会导致重启如何解决
Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
21 0
|
1月前
|
算法 Java UED
【JVM】分代收集算法:提升Java垃圾回收效率
【JVM】分代收集算法:提升Java垃圾回收效率
19 0
|
1月前
|
Java 程序员
探讨JVM垃圾回收机制与内存泄漏
探讨JVM垃圾回收机制与内存泄漏
|
3月前
|
Web App开发 存储 JavaScript
【JavaScript】垃圾回收与内存泄漏
JavaScript的*垃圾回收机制*是一种自动化的内存管理机制,用于检测和回收不再使用的内存资源,以便重新分配给其他需要的部分。JavaScript中的垃圾回收器负责跟踪和管理内存的分配和释放,使开发人员无需手动管理内存。 *内存泄漏*指的是程序中分配的内存空间无法被释放和回收,并且随着时间推移导致可用内存逐渐减少。
52 0
|
7天前
|
存储 缓存 监控
Java内存管理:垃圾回收与内存泄漏
【4月更文挑战第16天】本文探讨了Java的内存管理机制,重点在于垃圾回收和内存泄漏。垃圾回收通过标记-清除过程回收无用对象,Java提供了多种GC类型,如Serial、Parallel、CMS和G1。内存泄漏导致内存无法释放,常见原因包括静态集合、监听器、内部类、未关闭资源和缓存。内存泄漏影响性能,可能导致应用崩溃。避免内存泄漏的策略包括代码审查、使用分析工具、合理设计和及时释放资源。理解这些原理对开发高性能Java应用至关重要。
|
1月前
|
Java 程序员 Python
|
2月前
|
监控 Java 编译器
优化Go语言程序中的内存使用与垃圾回收性能
【2月更文挑战第5天】本文旨在探讨如何优化Go语言程序中的内存使用和垃圾回收性能。我们将深入了解内存分配策略、垃圾回收机制,并提供一系列实用的优化技巧和建议,帮助开发者更有效地管理内存,减少垃圾回收的开销,从而提升Go程序的性能。