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

通俗讲解JVM(三)

java冷知识:spring的版权被控制在vmware手里,其实spring的那一大堆东西,本质上是一个非标准的jee实现,

 java冷知识:spring的版权被控制在vmware手里,其实spring的那一大堆东西,本质上是一个非标准的jee实现,比如在jee里面用的inject,在spring里面就是autowire,当然spring曾经深刻滴影响了jee,所以有些东西比如di标准,是spring影响下制定出来的,所以spring的做法会比较特例一点。



1.直接内存


1.1Direct Memory

程序在运行时,不可避免的会访问系统内存,让我们来看一下jvm是如何帮我们进行处理的。

在jdk1.4中新加入了NIO类,引入了一种基于通道与缓存区的I/O方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,避免了在java堆和Native堆中来回复制数据。

操作系统的内存特点


  • 常见于NIO操作,用于数据缓冲区

  • 分配回收成本较高,但读写性能高

  • 不受JVM内存回收管理

  • 必须主动释放资源(ByteBuffer内部自动给我们调用了)

java并不能直接操作系统内存,而是通过cpu内部的系统将磁盘信息读取到系统的缓存区,然后提供给java缓存区,由java调用。需要将缓存复制一遍。

 分配的直接内存,操作系统和java都可以直接访问,减少了数据的访问时间和空间


 1.2分配与回收原理


  1. 使用了Unsafe对象完成直接内存分配回收,并且回收需要主动调用freeMemory 方法

  2. ByteBuffer的实现类内部,使用了Cleaner(虚引用)来检测ByteBuffer对象,一旦ByteBuffer对象被垃圾回收,那么就会由RefernceHandler线程通过Cleaner的clean方法调用freeMemory来释放直接内存

java中分配直接内存的方法(调用unsafe对象)


  • allocateMemory 返回分配内存的地址

  • setMemory

释放内存的方法(借助cleaner(虚引用类型),调用unsafe对象)


  • freeMemory 释放分配的内存


 1.3OutOfMemoryError异常

本机直接内存的分配不受java堆大小的限制,但是,既然是内存,肯定还是回受本机总内存大小以及处理器寻址空间的限制。服务器管理员在配置虚拟机参数时,会根据实际内存设置-Xmx等参数信息,但经常忽略直接内存,使得各个内存区域总和大于物理内存限制,从而导致动态扩展时候回出现OutOfMemoryError异常。


2.对象的创建

对象是如何创建的呢?当我们去new一个对象的时候,虚拟机接收到new指令,会先去检查这个指令的参数是否在常量池中定位到一个类的符号引用,并检查符号引用代表的类是否已经被加载、解析和初始化,如果没有,则需要先加载。


2.1内存的分配方式

加载完之后,便是内存的分配,对象所需要的内存在类加载完成后便可完全确定。这里介绍两种分配方式

第一种:指针碰撞

指针碰撞看起来不是很好理解,其实很简单。一块完整的内存,所有已经分配的内存在一起,空闲的内存放在一起。当需要分配空间的时候,就将指针向空闲内存移动分配的空间大小。

第二种:空闲列表

顾名思义,空闲列表就是记录内些空闲区域的列表。java堆内存并不能保证已分配的内存和未分配的内存完全分开,所以用指针碰撞难以实现内存的分配。而空闲列表则会记录空闲的内存区域,当需要分配内存时,便到列表中找到一块足够的空间,并修改列表中的内容。

选用哪种分配方式,这由java堆是否工整决定的。


2.2线程问题

以上两种情况处理单线程时没有问题,但是当出现多线程时会出现这么一个问题。

当A线程正在给a分配内存,指针还未移动时,这时B线程给b分配内存,记录的指针初始位置与未分配a对象时的位置相同。

两种解决方案:

第一种:原子性,对内存分配空间进行同步处理。

第二种:为每一个线程分配“私有“的内存空间,这里的私有并不是广义上的私有 ,它还是分配的堆内存,只不过是将堆分配成多个空间,每一个线程占有一块空间,这里的私有空间我们称它为本地线程分配缓冲(TLAB)。只有当这块区域用完时,才会进行同步锁定。

是否使用TLAB可以通过-XX:+/-UseTLAB参数来设定。

内存分配完成后,会将分配的内存空间初始化为零(不包括对象头),这样在使用时,即使不赋值也可以直接使用。

对象头中还存有很多信息,比如这是哪个类的对象实例,如何找到元数据信息、对象的哈希码、对象的GC分带年龄等。

接下来便会执行方法,将对象初始化。


之前跟着黑马的老师刷过一遍jvm,讲的真的非常棒,可以结合这PDF和课程一起刷

学习视频链接:

黑马程序员JVM完整教程,全网超高评价,全程干货不拖沓_哔哩哔哩_bilibili



深入理解JVM网盘链接
链接:https://pan.baidu.com/s/1iiMsS3vBWbLOxXstE1EpEw 
提取码:spoi



推荐阅读
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了Composer依赖管理的重要性及使用方法。对于现代语言而言,包管理器是标配,而Composer作为PHP的包管理器,解决了PEAR的问题,并且使用简单,方便提交自己的包。文章还提到了使用Composer能够避免各种include的问题,避免命名空间冲突,并且能够方便地安装升级扩展包。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • OpenMap教程4 – 图层概述
    本文介绍了OpenMap教程4中关于地图图层的内容,包括将ShapeLayer添加到MapBean中的方法,OpenMap支持的图层类型以及使用BufferedLayer创建图像的MapBean。此外,还介绍了Layer背景标志的作用和OMGraphicHandlerLayer的基础层类。 ... [详细]
  • Nginx Buffer 机制引发的下载故障
    Nginx ... [详细]
  • 寻求更强大的身份和访问管理(IAM)平台的企业正在转向云,并接受身份即服务(IDaaS)的灵活性。要为IAM选择正确的场外解决方案,业务管理人员和IT专业人员必须在实施之前评估安全 ... [详细]
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社区 版权所有