我的编程空间,编程开发者的网络收藏夹
学习永远不晚

java内存管理机制剖析(一)

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

java内存管理机制剖析(一)

最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下。

1.1 java内存区域

当java程序运行时,java虚拟机会将内存划分为若干个不同的数据区域,这些内存区域创建和销毁的时间各不相同,所承担的功能也不相同,他们各司其职,各尽所责。这些区域的划分如下图
java内存管理机制剖析(一)

运行时数据区主要有五个区,分别是 堆 ,方法区,虚拟机栈,本地方法栈,程序计数器,下面我来一一详细讲解这五个数据区

java堆是java虚拟机管理内存中最大的一块,它是被所有线程共享的一块内存区域,在虚拟机启动时创建,此内存的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在堆分配内存

java虚拟机规定,java堆可以处于物理上不连续的内存空间中,只要逻辑上连续即可。在实现时,既可以实现固定大小的,也可以是扩展的,可以通过配置-Xmx和-Xms来扩展大小。如果堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError

方法区

方法区也是被所有线程共享的一块内存区域,在Java虚拟机规范中,方法区是堆的逻辑组成部分,但他又被与堆区分开来,别名称为Non-Heap,它主要的存储内容有下面几点

  • 类型的完整有效名
  • 类型直接父类的完整有效名
  • 类型的修饰符(public,abstract,final的某个子集)
  • 类型的常量池
  • 域(Field)信息
  • 方法(Method)信息
  • 除了常量外的所有静态(static)变量

总结起来就是主要用于存储已被虚拟机加载的类信息,常量,静态变量,编译器编译后的代码等数据

这里我在介绍一下常量池,域信息和方法信息

—-常量池

常量池也称为运行时常量池(Runtime Constant Pool),用于存放编译期生成的各种字面量和符号引用,它是这个类型用到的常量的一个有序集合,包括实际的常量(String, Integer, 和Floating point常量)和类型,域和方法的符号引用
池中的数据项像数组项一样,是通过索引访问的。 因为常量池存储了一个类类型所使用到的所有类型,域和方法的符号引用,所以它在java程序的动态链接中起了核心的作用

—-域(Field)信息

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

—-方法(Method)信息

方法的相关信息包括:方法名, 方法的返回类型(或 void), 方法参数的数量和类型(有序的),方法的修饰符(public, private, protected, static, final, synchronized, native, abstract的一个子集),除了abstract和native方法外,其他方法还有保存方法的字节码(bytecodes)操作数栈和方法栈帧的局部变量区的大小

java虚拟机规范对方法区的限制比较宽松,除了和java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不是实现垃圾收集。垃圾收集行为在方法区也比较少出现,当方法区无法满足内存分配时,会抛出OutOfMemoryError

虚拟机栈

虚拟机栈是线程私有的,它的生命周期与线程相同,当我们start一个线程时,jvm会为当前线程开辟一块虚拟机栈,当当前线程死亡时,线程的虚拟机栈也会销毁。

代码中每个方法在执行的同时,都会创建一个栈帧(Stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

局部变量表存放了编译期可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用和returnAddreass类型

JVM对这个区域规定了两种异常情况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出SstackOverFlowError异常;如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryErro异常

本地方法栈

本地方法栈和虚拟机栈的作用是一样的,只不过本地方法栈是虚拟机执行java方法时开辟的栈,而本地方法栈是虚拟机用到Native方法时,开辟的栈。

程序计数器

程序计数器是一块较小的内存,它可以看作是当前线程的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时就是通过改变这个计数器的值来选取吓一跳需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能。

由于java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程指尖计数器互不影响,独立存储。

1.2 对象创建

了解了内存的数据区域,我们可以进一步了解对象是如何创建的了。这里先通过一张流程图一窥java的对象创建过程
java内存管理机制剖析(一)
可以看到,当虚拟机遇到一条new指令时,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经加载。如果没有,则执行加载。

加载完成后,便会在堆中为对象分配内存,JVM有两种分配方式①指针碰撞,②空闲列表,下面我详细讲讲这两种分配方式。

—-指针碰撞

当java堆中内存是整齐的,所有用过的内存都放一边,空闲的内存放在另一边,中间放着一个指针座位分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边摞动一段与对象大小相等的距离,这种分配就叫指针碰撞

—-空闲列表

当Java堆的内存并不是完整的,已分配的内存和空闲内存相互交错,JVM通过维护一个列表,记录可用的内存块信息,当分配操作发生时,从列表中找到一个足够大的内存块分配给对象实例,并更新列表上的记录。这种分配方式称为空闲列表

当JVM所采用的垃圾收集器带有压缩整理功能时,java堆是规整的,这个时候会采用指针碰撞分配内存,否则会采用空闲列表分配内存。对象创建是一个非常频繁的行为,进行堆内存分配时还需要考虑多线程并发问题,可能出现正在给对象A分配内存,指针或记录还未更新,对象B又同时分配到原来的内存,解决这个问题有两种方案:

  • 1、采用CAS保证数据更新操作的原子性;
  • 2、把内存分配的行为按照线程进行划分,在不同的空间中进行,每个线程在Java堆中预先分配一个内存块,称为本地线程分配缓冲(Thread Local Allocation Buffer, TLAB);

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

java内存管理机制剖析(一)

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java内存管理机制剖析(一)

最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下。1.1 java内存区域 当java程序运行时,java虚拟机会将内存划分为若干个不同的数据区域,这些内存区域创建和销毁的时间各不相同,所承担的功能也不相同,他们各
2023-06-02

golang内存管理机制解析

go语言采用垃圾回收机制自动管理内存,防止泄漏。内存划分为栈(局部变量)、堆(动态数据)、静态数据和mmap区。垃圾回收器检测并释放不再被引用的对象内存,包括标记阶段和清除阶段。实战案例演示了引用计数机制,当计数降为0时,垃圾回收器释放对象
golang内存管理机制解析
2024-04-23

Python内存管理机制

1 概述对于Python这样的动态语言,如何高效的管理内存,是很重要的一部分,在很大程度上决定了Python的执行效率。与大多数编程语言不同,Python中的变量无需事先申明,变量无需指定类型,程序员无需关心内存管理,Python解释器给你
2023-01-31

Golang的gc与内存管理深度剖析

Golang的gc与内存管理深度剖析随着互联网的发展,越来越多的公司和开发者开始采用Go语言(Golang)开发应用程序。Go语言以其高效的并发性能和简洁的语法受到了广泛的关注和喜爱。而作为一门现代编程语言,Go语言的垃圾回收(Garba
Golang的gc与内存管理深度剖析
2024-03-06

python内存管理机制是什么

Python内存管理机制是自动化的。Python使用引用计数来跟踪和回收对象的内存。每个对象都有一个引用计数,当引用计数减少到0时,对象就会被自动回收。除了引用计数,Python还使用垃圾收集器来检测和回收不再被引用的循环引用对象。垃圾收集
2023-08-31

go内存管理机制是什么

Go语言的内存管理机制是基于垃圾回收(Garbage Collection)的。Go语言中的内存管理是由垃圾回收器负责的,它会自动跟踪和释放不再使用的内存,以避免内存泄漏和野指针等问题。Go语言的垃圾回收器使用了标记-清除(Mark a
2023-10-27

CLR内存管理机制是什么

这篇文章主要介绍“CLR内存管理机制是什么”,在日常操作中,相信很多人在CLR内存管理机制是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”CLR内存管理机制是什么”的疑惑有所帮助!接下来,请跟着小编一起来
2023-06-17

unity内存管理机制是什么

Unity的内存管理机制是自动化管理的。Unity使用了一种称为垃圾回收(Garbage Collection)的技术来自动管理和释放内存。在Unity中,当您创建、加载或销毁游戏对象、资源或脚本实例时,Unity会自动跟踪和管理这些对象
2023-10-27

android内存管理机制是什么

Android的内存管理机制是一种动态的机制,主要包括以下几个方面:1. 内存分配:Android使用堆来分配内存。堆是一个运行时数据区域,用于存放对象实例。Android的堆分为两个部分:Java堆和Native堆。Java堆用于Java
2023-09-13

Golang闭包的内存管理机制

go语言中,闭包捕获外部变量的引用,延长了变量的生命周期;垃圾回收器自动管理闭包内存,释放空闲引用;使用闭包时需注意内存泄漏、外部变量修改和执行时间开销。Go 语言中闭包的内存管理简介闭包是一种函数嵌套在另一个函数中创建的可访问外部变量
Golang闭包的内存管理机制
2024-04-15

php内存管理机制与垃圾回收机制的示例分析

这篇文章给大家分享的是有关php内存管理机制与垃圾回收机制的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、内存管理机制先看一段代码:
2023-06-15

深度剖析java中JDK动态代理机制

摘要相比于静态代理,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象。代理模式使用代理模式必须要让代理类和目标类实现相同的接口,客户端通过代理类来调用目标方法,代理类会将所有的方法调用
2023-05-31

什么是Python的内存管理机制

Python的内存管理机制是Python解释器在运行时自动管理内存的一套机制,主要包括以下内容:一、引用计数;二、垃圾回收;三、内存分配。引用计数提供了一种简单高效的内存管理方式,但它无法解决循环引用的问题。
什么是Python的内存管理机制
2023-10-29

Python中什么是内存管理机制

本篇文章给大家分享的是有关Python中什么是内存管理机制,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。python的数据类型有哪些?python的数据类型:1. 数字类型,包
2023-06-14

Redis的内存管理机制是什么

Redis使用一种称为"内存驱动"的内存管理机制。该机制将所有数据存储在内存中,并通过使用LRU算法(最近最少使用)来管理内存中的数据。当内存达到设定的阈值时,Redis会根据LRU算法淘汰一些数据以释放空间。此外,Redis还可以通过将数
Redis的内存管理机制是什么
2024-05-07

Python内存管理机制的原理是什么

今天就跟大家聊聊有关Python内存管理机制的原理是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。小块空间的内存池在Python中,许多时候申请的内存都是小块的内存,这些小块内存
2023-06-17

JMX 剖析:深入探索 Java 应用程序的内部机制

Java 管理扩展 (JMX) 剖析:揭开 Java 应用内部运作的神秘面纱
JMX 剖析:深入探索 Java 应用程序的内部机制
2024-02-19

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录