【java】java虚拟机JVM

本文详细介绍了Java中的类加载器如何加载类,运行时数据区的构成,以及堆、栈的区别。重点探讨了垃圾回收机制,包括垃圾回收线程、可达性分析和不同类型的垃圾回收算法。同时,文章还涵盖了内存泄露和溢出的原因,以及如何通过垃圾收集器管理和优化内存使用。
摘要由CSDN通过智能技术生成

 类加载器(Class Loader)

负责将类的字节码加载到内存中,并生成相应的 Class 对象。类加载器通常采用委托模型,根据特定的加载规则从不同的位置加载类,如本地文件系统、网络等。

运行时数据区

方法区(Method Area)

Java堆(Java Heap)

Java虚拟机栈(Java Virtual Machine Stacks)

本地方法栈(Native Method Stack)

堆vs栈

Java中,堆(Heap)主要用于存储对象实例,而栈(Stack)则用于存储方法的局部变量和调用信息。

堆(Heap):堆是JVM管理的最大的一块内存空间,主要用于存放通过new操作符创建的对象和数组。堆内存是由垃圾回收器(Garbage Collector)自动管理的,不需要程序员手动干预。在Java程序运行过程中,不断有新的对象被创建并分配到堆上,同时也会有不再使用的对象被垃圾回收器回收以释放空间。

栈(Stack):栈也称为虚拟机栈,它是每个线程私有的内存区域,用于存放该线程执行的方法调用(方法帧)以及方法中的局部变量。每当一个方法被调用时,JVM会在当前线程的栈中创建一个栈帧,用来保存方法的局部变量表、操作数栈、动态链接和方法返回地址等信息。当方法执行完毕,对应的栈帧就会被销毁。

 程序计数器(Program Counter Register)

垃圾回收机制

在Java中,垃圾回收机制是JVM的一个核心功能,它允许程序员不需要手动管理内存释放。这一机制确保了对象在不再被引用时能够被自动回收,从而避免内存泄漏。以下是垃圾回收机制的关键要点:

垃圾回收线程

JVM内部有一个专门的垃圾回收线程,它的优先级较低,通常在系统空闲或堆内存不足时才会触发执行。

对象可达性分析

垃圾回收器会定期进行可达性分析,以确定哪些对象不再被任何活动的线程引用,这些对象被认为是垃圾,可以被回收。

垃圾回收算法

标记-清除(Mark and Sweep)

复制(Copying)

标记-整理(Mark and Compact)

垃圾回收器

不同的JVM实现可能提供不同的垃圾回收器,例如HotSpot JVM就有多个垃圾回收器可供选择,包括Serial、Parallel、CMS和G1等。

性能监控与调优

在处理内存溢出、内存泄漏或进行程序性能调优时,可能需要对垃圾回收机制进行监控和调节。这可以通过JVM提供的监控工具和参数来实现。

内存泄露

内存泄露在Java中主要指的是程序中存在一些不再使用的对象,但这些对象的内存却没有被及时释放,导致程序的内存占用持续增加。

导致内存泄露的情况:

长生命周期对象持有短生命周期对象的引用:如果长生命周期对象(如静态变量)持有短生命周期对象的引用,并且没有及时释放这个引用,那么短生命周期对象的内存就无法被垃圾回收器回收。

静态集合对象未及时清理:静态集合如果一直被引用而不进行清理,它们所包含的对象也将无法被垃圾回收器回收,从而导致内存泄露。

资源未关闭:在使用数据库连接、文件流、网络连接等资源时,如果在不再需要这些资源时没有及时关闭它们,也会导致内存泄露。

监听器未注销:在使用监听器(如事件监听器)时,如果没有及时取消注册或注销监听器,这也可能导致内存泄露,因为这些监听器对象会一直被事件源持有引用。

内存溢出

Java虚拟机内存溢出(OutOfMemoryError)是指在程序运行过程中,由于内存分配不足或内存管理不当导致无法再分配足够的内存给新的对象,从而导致程序无法继续正常执行的情况。

导致内存溢出的情况:

堆内存溢出:堆是Java虚拟机用于存储对象实例和数组等动态分配内存的区域。当程序创建了大量对象,而无法及时进行垃圾回收时,堆内存可能会耗尽,导致OutOfMemoryError。

方法区内存溢出:方法区用于存储类的结构信息、常量、静态变量等数据。当应用程序动态加载大量类或者运行时产生大量的常量字符串时,方法区可能会耗尽内存,导致OutOfMemoryError。在Java 8及之前的版本中,方法区内存溢出通常被称为永久代溢出(PermGen Space),而在Java 8及之后的版本中使用了元空间(Metaspace)代替永久代。

栈内存溢出:每个线程在运行时都会创建一个虚拟机栈,用于存储方法的局部变量、操作数栈等信息。如果栈的深度超过了虚拟机所允许的最大深度,就会导致栈内存溢出。

本地方法栈溢出:与虚拟机栈类似,本地方法栈用于执行本地方法。如果本地方法的递归调用层次太深,就会导致本地方法栈溢出。

直接内存溢出:直接内存是通过NIO(New I/O)引入的一种机制,它允许Java程序直接在堆外分配内存。如果程序频繁地分配大量的直接内存,而又没有及时释放,就可能导致直接内存溢出。

垃圾收集器

执行引擎(Execution Engine)

负责执行 Java 字节码。执行引擎通常包括解释器和即时编译器(Just-In-Time Compiler,JIT Compiler)。解释器逐行解释字节码并执行,而即时编译器则将字节码编译成本地机器码,提高程序的执行效率。

本地方法接口(Native Method Interface)

允许Java应用程序调用本地方法库(Native Library),与底层操作系统和硬件交互。

本地方法库(Native Library)

包含了一组与操作系统相关的本地方法实现,可以由Java应用程序调用。

专业名词

Java中的引用

对不同的引用类型,JVM 在进行GC 时会有着不同的执行策略

4种引用强度依次逐渐减弱。

强引用(Strong Reference)

软引用(Soft Reference)

弱引用(Weak Reference)

虚引用(Phantom Reference)

  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岩塘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值