首页 > 系统相关 >JVM 内存结构、垃圾回收机制与并发容器

JVM 内存结构、垃圾回收机制与并发容器

时间:2024-07-24 21:55:11浏览次数:15  
标签:Java 回收 并发 线程 内存 JVM

目录

一、JVM 内存结构

 1. 程序计数器(Program Counter Register):

 2. Java 虚拟机栈(JVM Stack):

  3.本地方法栈(Native Method Stack):

  4.堆(Heap):

  5.方法区(Method Area):

二、垃圾回收机制

  1.标记-清除算法:

  2.复制算法:

  3.标记-整理算法:

  4.分代收集:

三、并发容器

  1.ConcurrentHashMap:

  2.CopyOnWriteArrayList:

  3. BlockingQueue:

  4.ConcurrentSkipListMap:


  在现代程序设计中,Java 语言以其强大的功能和广泛的应用被广泛采用。理解 Java 虚拟机(JVM)的内存结构、垃圾回收机制以及并发容器,能够帮助开发人员有效管理内存、提升性能,并编写高效的并发程序。本文将深入探讨这些主题,以期帮助读者更好地理解 Java 的内在机制。

一、JVM 内存结构

Java 虚拟机(JVM)内存结构可以分为几个主要部分:

 1. 程序计数器(Program Counter Register):

程序计数器是一块较小的内存空间,用于记录当前线程所执行的字节码的行号指示器。每个线程都有一个独立的程序计数器,因此它是线程私有的。程序计数器的存在使得多线程执行时能够准确地上下文切换。

 2. Java 虚拟机栈(JVM Stack):


JVM 栈用于存储局部变量、操作数栈、动态链接和方法的返回地址等信息。每个线程都有自己的 JVM 栈,栈中的数据是以帧(Frame)的形式组织的,每当一个线程调用一个方法时,会为该方法创建一个新的帧并压入栈中,方法执行完成后,相应的帧会被弹出。

  3.本地方法栈(Native Method Stack):


本地方法栈与 Java 虚拟机栈类似,但它用于支持 JNI(Java Native Interface)调用的本地方法。在这个栈中保存的是本地方法运行所需的栈帧。

  4.堆(Heap):


Java 堆是 JVM 中最大的一块内存区域,所有的对象实例和数组都在这里进行分配。Heap 是线程共享的,因此必须使用同步机制来保证其线程安全。在许多情况下,Java 堆的大小可以通过 JVM 的启动参数进行配置,如 -Xms(初始堆大小)和 -Xmx(最大堆大小)。

  5.方法区(Method Area):


方法区用于存放类信息(如类字节码、常量池、静态变量等)。在 JDK6 之前,方法区被称为永久代(PermGen)。在 JDK8 中,方法区被重新设计成为元空间(Metaspace),它的内存不再限制于 JVM 堆中,而是使用本地内存来存储。

二、垃圾回收机制

  Java 提供了自动的垃圾回收(Garbage Collection, GC)机制,通过及时回收不再使用的对象来有效管理内存。Java 的垃圾回收机制主要包括以下几种算法和策略:

  1.标记-清除算法:


  垃圾回收器首先标记所有可达的对象,然后清除未标记的对象。这种方法简单但存在内存碎片的问题。

  2.复制算法:


  该算法将可用内存分为两块半区。在其中一块中进行对象的分配,当这块内存满时,就将存活的对象复制到另一块半区,然后清空原先的内存。这种方法避免了内存碎片的产生,但代价是需要额外的内存空间。

  3.标记-整理算法:


  结合了标记-清除和复制算法的优点。标记所有可达对象之后,将存活对象复制到内存的一端,然后清理其他未标记的对象。这种方式同样避免了内存碎片问题。

  4.分代收集:


  Java 的垃圾回收器采用分代收集的策略,将堆内存分为新生代和老年代。新生代的对象生命周期相对短暂,而老年代的对象生命周期较长。新生代的垃圾回收发生频繁,而老年代的垃圾回收相对较少,优化了内存回收的效率。

  Java 中的垃圾回收器(如 G1、CMS、Parallel GC 等)各具特点,开发者可以根据具体的应用场景选择合适的垃圾回收器。

三、并发容器

  并发容器是指在多线程环境下,能够安全地被多个线程同时访问的集合类。Java 提供了一系列并发容器,以应对高并发情况下的数据共享和操作的问题。这些并发容器主要包括:

  1.ConcurrentHashMap:


  这是一个线程安全的哈希表,支持高并发的读写操作。ConcurrentHashMap 使用分段锁的策略,将整个集合分为多个段,每个段可以独立加锁,从而提高并发性能。

  2.CopyOnWriteArrayList:


  该容器在写操作时会进行复制,因此在读操作时不会发生竞争。CopyOnWriteArrayList 适合读多写少的场景,能够避免加锁带来的性能损耗。

  3. BlockingQueue:


  Java 提供了多种阻塞队列(如 ArrayBlockingQueue、LinkedBlockingQueue 等),支持线程间的协作。当队列为空时,消费者线程会被阻塞,直到有新数据入队;当队列满时,生产者线程会被阻塞,直到有数据出队。

  4.ConcurrentSkipListMap:


  这是一个基于跳表(SkipList)实现的线程安全的有序映射。与 ConcurrentHashMap 不同,它是有序的,并且允许并发的读写操作,适合用于需要维护排序的场景。

标签:Java,回收,并发,线程,内存,JVM
From: https://blog.csdn.net/XHgga_/article/details/140674195

相关文章

  • 一文弄懂JVM类加载器与双亲委派机制
    类的加载器完成类的加载环节中的装载阶段的工作(通过一个类的全限定名来获取该类的二进制字节流,且这个动作在虚拟机**外部实现**,即开发者可以决定如何去获取所需的类),且**不会影响后续的链接和初始化阶段,但类的加载器的存在使得类不会卸载**。类的加载器的意义:加载器的意义......
  • 02-2 【编写loader工程内容】检测内存容量
    方法:利用BIOS中断来检测内存容量,具体是BIOSINT0x15(或INT15H)具体使用方法:参考文档链接:https://wiki.osdev.org/Detecting_Memory_(x86)实操(1)首先定义一个结构体因为内存是分成好多块的,有一些是已经被硬件占用了:因此检测内存返回的结构体应该是个结构体数组......
  • 在C++里如何释放内存的时候不调用对象的析构函数?
    今天,看到一个有趣的面试题,问题是:在C++里如何释放内存的时候不调用对象的析构函数?之所以有趣,是因为这个问题违反了C++中资源管理的RAII(资源获取即初始化),它要求资源的释放应当和对象的生命周期紧密相关。在正常情况下,当对象离开其作用域时,它的析构函数被调用,以释放它所管理的......
  • 【C语言】动态内存管理详解!!!
    目录为什么存在动态内存分配?动态内存函数的介绍常见的动态内存错误几个经典的笔试题 C/C++程序的内存开辟柔性数组为什么存在动态内存分配?在动态内存函数之前,我们知道的内存开辟有两种。1. 在栈空间上开辟四个字节。intval=20;2. 在栈空间上开辟10个字节的......
  • Java内存模型全解析:解决共享变量可见性与指令重排难题
    本期说一下Java内存模型(JavaMemoryModel,JMM)及共享变量可见性问题。“以下内容出自本人整理的面试秘籍。点击此处,无套路免费获取面试秘籍JMM是什么?答:Java内存模型(JavaMemoryModel,JMM)抽象了线程和主内存之间的关系就比如说线程之间的共享变量必须存储在主内存......
  • 关于内存条选择的一些看法
    先叠甲,只是个人看法以及近期学的知识,欢迎大家讨论,我的知识面也不够全面电脑的内存条分为DDR4与DDR5需要与主板的卡槽对应,挑选需要关注三个核心:容量,频率,参数。先说一下容量,内存条的容量的选择关乎于你的日常工作量,需不需要多开各类办公软件,以及你玩什么类型的游戏,容量越大越流畅......
  • Java 内存模型
    Author:ACatSmilingSince:2024-07-24概念Java内存模型:JavaMemoryModel,简称JMM,是Java语言中定义的一组规则和规范,用于解决多线程环境下的内存可见性和有序性问题。JMM确定了线程之间如何通过内存进行交互,并规定了变量的读取和写入操作的行为。JMM能干吗?通过JMM来......
  • Failed to create JVM.JVM Path:D:\IntelliJ IDEA 2024.1.4\jbr Error launching I
     IDEA修改启动参数掉大坑!情况说明:在Help>EditCustom VMOptions修改IDEA的VM产生之后无法打开(重启/重装多次依然无法打开),修改C盘的idea64.exe.vmoptions和安装目录的idea64.exe.vmoptions依然无法启动!,后面把IDEA安装目录的jar文件夹删了,又重装JDK。由于我有多个JDK环境,......
  • 记一次Echart 内存泄露问题排查
    最近发现一个web项目总是莫名其妙的内存增长,然后进行定位后来发现问题大概率出在Eharts上。于是乎就开始搜索关于echarts内存增长的一些例子,但是都没有结果。其中翻博客时发现甚至有人换成一维数组就问题就解决了,当然这个试过之后对我来说解决不了问题。(这样能解决掉也真是离......
  • 内存管理-22-KASLR
    基于msm-5.4一、简介1.什么是KASLRKASLR是kerneladdressspacelayoutrandomization的缩写,直译过来就是内核地址空间布局随机化。KASLR技术允许将kernelimage映射到vmalloc区域的任何位置(待确认哦)。2.引入KASLR的原因没有KASLR的时候,kernelimage都会映射到一个固......