jvm基础

运行时数据区域

每个区域都有各自的用途,以及创建和销毁的时间。

  • 程序计数器:一块较小的内存,可以看作当前线程所执行的字节码的行号指示器,通过修改这个技术器的值来选取下一条需要执行的字节码指令。分支、循环、跳转、线程恢复等基础功能都依赖计数器来完成。JVM的多线程是通过线程轮流处理切换、分配处理器执行时间来实现的,在任何时刻一个处理器中只执行一个线程中的指令。为了线程切换后能再次回到正确的执行位置,每个线程需要各自独立的程序计数器,互不影响。因此线程私有,生命周期随线程。
  • 虚拟机栈:描述java方法执行的内存模型,每个方法被执行的时,jvm都会同步创建一个栈帧用于存储局部变量表(存放了编译期可知的各种基础数据类型(long和double类型数据占用两个变量槽)8种、对象引用(reference类型)、returnAddress类型(指向一条字节码指令的地址),局部变量表所需内存空间在编译期间完成分配,当进入一个方法时,栈帧中需要的局部变量空间是完全确定的且在运行期间不会改变局部变量表的大小(变量槽的数量))、操作数栈、动态连接、方法出口等信息。每个方法被调用到执行完毕,对应着一个栈帧的从入栈到出栈的过程。线程私有,生命周期随线程。线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常,如果栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常。可通过-Xss调整大小,内存不足时抛出StackOverflowError(如果线程请求的栈深度大于虚拟机所允许的深度)或者OutOfMemoryError(如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存)。
  • 本地方法栈:为使用到的native方法服务。
  • 堆:jvm所管理的内存中最大的一块,被所有线程共享的一块区域,虚拟机启动时创建,唯一目的就是存放对象实例(对象实例和数组)。在分配内存的角度,所有线程共享的java堆可划分出多个线程私有的分配缓冲区(Thead Local Alloction Buffer,TLAB)。通过参数-Xmx和-Xms进行设定内存大小,若没有足够的内存分配对象实例,且堆无法扩展,则会抛出OutOfMemoryError异常。
  • 方法区:存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。(-XX:MaxPermSize 进行设置内存大小),JDK8已经完全废弃了永久代的概念,在本地内存(Native Memory)中实现的元空间(Meta-space)来代替,也就是说现在存储的地方全部转移到了元空间。针对这个区域的回收主要是针对常量池的回收和类型的卸载。
  • 运行时常量池:它是方法区的一部分,Class文件除了有类的版本、字段、方法、接口等描述信息外,还有就是常量池表,用于存储编译期间生成的各种字面量与符号引用,并在类加载后存放到方法区的运行时常量池中。具有动态性,并不要求常量一定只有在编译期才能产生,并非预置入Class文件中常量池的内容才能进入方法区运行常量池,运行期间也能将新的常量放入池中,String.intern() 方法。受方法区内存限制,常量池无法申请到内存时也会抛出OutOfMemoryError异常。
  • 直接内存:不是虚拟机运行时数据区域的一部分。也不是jvm规范定义的内存,也会被频繁使用,也可能引起OOM。 比如NIO中引入了一种基于通道(channel)和缓冲区(buffer)的I/O方式,通过Native函数库直接分配堆内存,通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。不受堆内存限制。但会受本机总内存大小和处理器寻址空间的限制。可通过-XX:MaxDirectMemorySize调整大小,内存不足时抛出OutOf-MemoryError或者OutOfMemoryError:Direct buffer memory

 

  • 字面量就是基础类型(int、short、long、char......)的表示法
  • 符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。
  •  直接引用可以是

    (1)直接指向目标的指针(比如,指向“类型”【Class对象】、类变量、类方法的直接引用可能是指向方法区的指针)

    (2)相对偏移量(比如,指向实例变量、实例方法的直接引用都是偏移量)

    (3)一个能间接定位到目标的句柄

    直接引用是和虚拟机的布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经被加载入内存中了

对象的创建过程

编译为class文件后,jvm加载到内存,

1.当遇到一个new指令是,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析、初始化。如果没有必须执行相应的类加载过程。

2.类加载检查通过后,给新生对象分配内存空间,内存的大小在类加载完成后是完全确定的,也就是从堆中划分出一块确定大小的内存。(分配的方式:a.如果内存是绝对规整的,被使用的内存放一边,空闲的另一边,中间放着一个指针作为分界点的指示器,所分配内存就是将指针像空闲空间方向挪动一段与对象大小相等的距离---指针碰撞。b.如果内存不规整,已被使用的内存和空闲的内存相互交错在一起,jvm维护一个列表,记录了那些内存可用,分配的时候找一块足够大的内存空间划给对象实例,并更新列表记录----空闲列表)。划分内存时,创建对象的过程频繁且在并发情况下,不是线程安全的。需要对内存分配的动作进行同步处理:11.采用CAS和失败重试保证更新操作原子性。22.把内存分配的动作按照线程划分在不同的空间之中进行,每个线程在java堆中预先分配一小块内存(本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),在各自的本地缓冲区中进行分配,只有缓冲区用完了才需要同步锁定,通过-XX:+/-UseTLAB参数进行设定。

3.分配完后,将分配到的内存空间(不包括对象头)都初始化为0,保证了对象实例字段在代码中可不不赋初始值就可直接使用,程序访问这些字段的数据时为零值。还需要进行额外的设置,对象属于那个类、元数据信息怎么找、对象哈希码、GC分代年龄、偏向锁等,存放在对象头中。

4.从jvm角度,对象已经产生,但从java角度才刚刚开始--构造函数,即class文件中的<init>()方法还没执行。

对象的内存布局

对象在jvm堆中可分为三个部分:对象头、实例数据、对齐填充。

对象头的Mark Word,除此之外就是类型指针,即对象指向它的类型元数据的指针,通过这个指针确定对象是那个类的实例。如果对象是数组,那么对象头里还需要一块用于记录数组长度的数据。可以确定普通对象的大小,如果数组长度不固定,则无法确定数组对象的大小。

实例数据是对象真正存储的有效信息(有存储顺序)。

对齐填充仅仅起着占位符的作用,jvm要求对象起始地址必须是8字节的整数倍,也就是对象大小必须是8字节的整数倍,如果不是则通过对齐填充来补全。

对象的定位访问

通过栈上的reference数据来操作堆上的具体对象,访问方式主要有句柄直接指针

  • 使用句柄访问,java堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄包含了对象实例数据与类型数据各自具体的地址信息。reference中存储的是稳定句柄地址,在对象移动时(垃圾收集时移动对象)只会改变句柄中实例数据指针,reference本身不会被修改。
  • 使用直接指针访问,java堆中对象的内存布局就是必须考虑如何放置访问类型数据的相关信息,reference中存储的直接就是对象地址,只访问对象本身,不用多一次间接访问的开销。通过直接指针速度块,节省了一次指针定位的时间开销(默认的方式)

-XX:+HeapDumpOnOutOfMemoryError 出现内存溢出异常时dump出当前内存堆转存储快照。

堆溢出OMM--总容量到了最大堆的容量限制后就会产生内存溢出异常。-Xms10m -Xmx10m 设置堆大小。

虚拟机栈和本地方法栈溢出---  -Xss 设置栈容量大小。

  • 线程请求的栈深度大于虚拟机所允许的最大深度(递归),将抛出StackOverflowError。
  • 栈内存扩展时,无法申请足够的内存,抛出OOM。

方法区和运行时常量池溢出

jdk8中使用元空间代替永久代。-XX:PermSize=6M -XX:MaxPermSize=6M 设置永久代大小(jdk7以上不生效了)

无论是在JDK 7中继续使用-XX:MaxPermSize参数或者在JDK 8及以上版本使用-XX:MaxMeta-spaceSize参数把方法区容量同样限制在6MB。自JDK 7起,原本存放在永久代的字符串常量池被移至Java堆之中,所以在JDK 7及以上版本,限制方法区的容量     是毫无意义的。string.intern()会见首次遇到的字符串放到常量池中。

通过代理堆类进行增强时,增强的类越来越多,就需要越大的方法区以保证动态生成的新类型可载入内存,可能就会出现方法区溢出。在经常运行时生成大量动态类的应用场景里,就应该特别关注这些类的回收状况。

在JDK 8以后,永久代便完全退出了历史舞台,元空间作为其替代者登场。

-XX:MaxMetaspaceSize:设置元空间最大值,默认是-1,即不限制,或者说只受限于本地内存大小。

-XX:MetaspaceSize:指定元空间的初始空间大小,以字节为单位,达到该值就会触发垃圾收集进行类型卸载,同时收集器会对该值进行调整:如果释放了大量的空间,就适当降低该值;如果释放了很少的空间,那么在不超过-XX:MaxMetaspaceSize(如果设置了的话)的情况下,适当提高该值。

-XX:MinMetaspaceFreeRatio:作用是在垃圾收集之后控制最小的元空间剩余容量的百分比,可减少因为元空间不足导致的垃圾收集的频率。类似的还有-XX:Max-MetaspaceFreeRatio,用于控制最大的元空间剩余容量的百分比。

 

本机直接内存溢出

直接内存的容量可以通过-XX:MaxDirectMemorySize参数指定,不指定默认和堆的最大值一样。dump文件里不会有明显的异常情况。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
08-10
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值