热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java占位符填充_Java内存区域与内存溢出异常

对于java程序员来说,虚拟机自动内存管理机制帮助javer们管理内存,不需要再deletefree,不容易出现内存泄漏和溢出问题,也正因为如此,一旦出现了泄露和溢出,如果不了解虚

对于java程序员来说,虚拟机自动内存管理机制帮助javer们管理内存,不需要再delete/free,不容易出现内存泄漏和溢出问题,也正因为如此,一旦出现了泄露和溢出,如果不了解虚拟机是如何使用内存的,那么排查将非常艰难.

一. 我们先来了解一下java内存的划分.
eb57b3552a5a587f1d5477c33ca788d7.png

由图可以看出,java内存划分分为两种类型,一种是所有线程共享的数据区,另一种是线程隔离的数据区.

程序计数器:

  1. 是内存中较小的一块空间,可以看作是当前线程所执行的字节码的行号指示器.
  2. 每个线程都有一个线程指示器,用于多线程切换时记录当前执行的行号.
  3. 当线程执行java方法时,计数器记录字节码的地址,如果正在执行Native方法,这个计数器值为空(Underfined)
  4. 此内存是唯一一个没有规定OutOfMemoryError情况的区域.
  5. 线程私有

java虚拟机栈:

  1. 每个方法在执行的时候都会创建一个栈帧,存储局部变量表,操作数栈,动态链接,方法出口等信息.一个方法从调用到执行完成的过程,就是一个栈帧在虚拟机栈中入栈到出栈的过程.
  2. 局部变量表存放了编译器可知的各种基本数据类型(boolean,byte,char,short,int,float,long,double),对象引用和returnAddress类型.其中64位的long和double会占用2个局部变量空间,其余的数据只占用一个.
  3. 局部变量表所需的内存空间在编译器完成分配,当进入一个方法时,所需要的局部变量空间是完全确定的.在方法运行期间不会改变局部变量表的大小
  4. 本区域两种异常情况:线程请求栈深超过所允许的深度,抛出StackOverflowError异常;如果本区域可以动态扩展,并且无法申请到足够的内存,会抛出OutOfMemoryError异常.
  5. 线程私有

本地方法栈:

  1. 与虚拟机栈发挥的作用非常相似,不同的是本地方法栈为虚拟机使用到的Native方法服务.
  2. 虚拟机规范对本区域的语言,方式,数据结构没有强制规定,可以自由实现.
  3. Sun HotSpot虚拟机将本区域与虚拟机栈合二为一.
  4. 抛出异常同虚拟机栈
  5. 线程私有

java堆:

  1. java虚拟机管理的内存中最大的一块,也是GC工作的主要区域.
  2. 此内存存放对象实例(对象,数组),规范中规定所有对象实例都在这里分配内存.
  3. 栈上分配和标量替换是的规范不再绝对.
  4. java堆可以处于物理上不连续的内存空间中,只要逻辑连续即可.
  5. 线程共享

方法区:

  1. 用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.
  2. 可以实现垃圾回收,但回收成果很小,hotSpot将方法区列为永久代,进行垃圾回收.
  3. java虚拟机规范将方法区描述为堆的一个逻辑部分,但却有另一个名字Non-Head(非堆)
  4. 无法满足内存分配的需求时,将抛出OutOfMemoryError异常.
  5. 线程共享

运行时常量池:

  1. 是方法区的一部分.
  2. 运行时常量池存放编译期生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行期常量池存放.
  3. 运行时常量池具备动态性,并不要求只有编译器才能产生,运行期间可以将新的常量放入池中.
  4. 作为方法区的一部分,自然受到方法去内存限制,无法再申请内存时抛出OutOfMemoryError.

直接内存:

  1. 不是虚拟机运行时数据区的一部分,也不是虚拟机规范定义的内存区域,但被频繁使用,也会导致OutOfMemoryError出现.
  2. 直接内存不受java堆大小的限制.会受到本机总内存大小及处理器寻址空间的限制.
二. 下面来讲解各内存是如何创建,布局和访问的.首先讲解堆中内存的分配问题.

对象的创建:

  1. 虚拟机遇到new指令时,检查到常量池中能否定位一个类的符号引用,并检查这个符号引用代表的类是否已加载,解析和初始化过,如果没有,那必须先执行类的加载过程.
  2. 在类加载检查通过后,为新生对象分配内存.对象所需的内存大小已经完全确定,分配内存分为:指针碰撞和空闲列表两种方式.区别时java堆中内存空间是否规整决定方式.
  3. 划分内存空间需要注意并发问题.
  4. 划分空间后,内存空间初始化为零值(不包括对象头)
  5. 接下来,虚拟机对对象进行必要的整理,将这些信息存放到对象头中.已虚拟机角度看,对象创建已经完成.
  6. java程序上,开始执行初始化方法.对象创建完成.

对象的内存布局:

  1. 对象头(Header):对象头包含两部分信息,一部分:存储对象自身的运行时数据,如哈希码,GC分代年龄,锁状态标志等,这部分数据在31和64虚拟机中占32bit和64bit,官方称为"Mark Word";另一部分是:类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针确定这个对象是哪个类的实例.
  2. 实例数据(Instance Data):是对象真正存储的有效信息,也是程序代码中定义的各种类型的字段内容.
  3. 对齐填充(Padding):这部分并不是必然存在,也么有特别的含义,仅仅是占位符的作用.对象的大小必须是8的整数倍,这部分用来对齐.

对象的访问定位:

对象的访问通过栈上reference数据来操作堆上的具体对象,java虚拟机只规定了对象的引用,没有规定该如何去定位,这部分又虚拟机实现而定.主流方式有二

  1. 句柄访问:Java堆中会划分出一块内存来作为句柄池,reference中存储对象的句柄地址,句柄中包含了对象实例数据与类型数据各自的具体地址信息.
  2. 直接指针访问:java堆对象的布局中就必须放置访问类型数据的相关信息,而reference中存储的直接就是地址.

两种方式各有优势.句柄访问好处是reference中存储的是稳定的句柄地址,在对象被移动时只会改变句柄中的实例数据指针,而reference本身不修改.

使用指针访问的好处是速度更快,节省了一次指针定位的时间开销.虚拟机Sun HotSpot使用指针访问.

本节内容到此结束,内容为书本知识的总结,切勿认为是抄袭.

致词,感谢.



推荐阅读
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • 如何高效学习鸿蒙操作系统:开发者指南
    本文探讨了开发者如何更有效地学习鸿蒙操作系统,提供了来自行业专家的建议,包括系统化学习方法、职业规划建议以及具体的开发技巧。 ... [详细]
  • Java虚拟机及其发展历程
    Java虚拟机(JVM)是每个Java开发者日常工作中不可或缺的一部分,但其背后的运作机制却往往显得神秘莫测。本文将探讨Java及其虚拟机的发展历程,帮助读者深入了解这一关键技术。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • Golang与微服务架构:构建高效微服务
    本文探讨了Golang在微服务架构中的应用,包括Golang的基本概念、微服务开发的优势、常用开发工具以及具体实践案例。 ... [详细]
  • 本文详细记录了一位Java程序员在Lazada的面试经历,涵盖同步机制、JVM调优、Redis应用、线程池配置、Spring框架特性等多个技术点,以及高级面试中的设计问题和解决方案。 ... [详细]
  • 本文档旨在提供C语言的基础知识概述,涵盖常量、变量、数据类型、控制结构及函数定义等内容。特别强调了常量的不同类型及其在程序中的应用,以及如何正确声明和使用函数。 ... [详细]
  • Vue CLI 基础入门指南
    本文详细介绍了 Vue CLI 的基础使用方法,包括环境搭建、项目创建、常见配置及路由管理等内容,适合初学者快速掌握 Vue 开发环境。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 在Qt框架中,信号与槽机制是一种独特的组件间通信方式。本文探讨了这一机制相较于传统的C风格回调函数所具有的优势,并分析了其潜在的不足之处。 ... [详细]
  • Python游戏开发实战:外星人入侵项目详解
    本文详细介绍了使用Python进行《外星人入侵》游戏开发的全过程,包括环境搭建、游戏逻辑设计及代码实现等关键步骤,适合对游戏开发感兴趣的朋友参考。 ... [详细]
  • 本文详细记录了一位求职者在搜狐进行的两次面试经历,包括面试的具体时间、面试流程、技术问题及个人感受。通过本次面试,作者不仅获得了宝贵的经验,还成功拿到了搜狐的录用通知。 ... [详细]
  • 我整理了HMOV四大5G旗舰的参数,可依然没能拯救我的选择困难症
    伊瓢茕茕发自凹非寺量子位报道|公众号QbitAI报道了那么多发布会,依然无法选出要换的第一部5G手机。这不,随着华为P40系列发布,目前国 ... [详细]
  • 本文详细介绍了 Java 中 org.w3c.dom.Node 类的 isEqualNode() 方法的功能、参数及返回值,并通过多个实际代码示例来展示其具体应用。此方法用于检测两个节点是否相等,而不仅仅是判断它们是否为同一个对象。 ... [详细]
  • 深入解析JVM内存模型与分配机制
    本文详细探讨了JVM内存结构的主要组成部分,包括Java虚拟机栈、Java堆、方法区等,并深入分析了HotSpot虚拟机的分代收集策略及其对不同内存区域的管理方式。 ... [详细]
author-avatar
一二三
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有