热门标签 | 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



推荐阅读
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送www方式的数据。HTTP协议采用了请求响应模型。客服端向服务器发送一 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 本文详细介绍了Java代码分层的基本概念和常见分层模式,特别是MVC模式。同时探讨了不同项目需求下的分层策略,帮助读者更好地理解和应用Java分层思想。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 本文详细解析了客户端与服务器之间的交互过程,重点介绍了Socket通信机制。IP地址由32位的4个8位二进制数组成,分为网络地址和主机地址两部分。通过使用 `ipconfig /all` 命令,用户可以查看详细的IP配置信息。此外,文章还介绍了如何使用 `ping` 命令测试网络连通性,例如 `ping 127.0.0.1` 可以检测本机网络是否正常。这些技术细节对于理解网络通信的基本原理具有重要意义。 ... [详细]
  • 阿里巴巴终面技术挑战:如何利用 UDP 实现 TCP 功能?
    在阿里巴巴的技术面试中,技术总监曾提出一道关于如何利用 UDP 实现 TCP 功能的问题。当时回答得不够理想,因此事后进行了详细总结。通过与总监的进一步交流,了解到这是一道常见的阿里面试题。面试官的主要目的是考察应聘者对 UDP 和 TCP 在原理上的差异的理解,以及如何通过 UDP 实现类似 TCP 的可靠传输机制。 ... [详细]
  • 该大学网站采用PHP和MySQL技术,在校内可免费访问某些外部收费资料数据库。为了方便学生校外访问,建议通过学校账号登录实现免费访问。具体方案可包括利用学校服务器作为代理,结合身份验证机制,确保合法用户在校外也能享受免费资源。 ... [详细]
  • 如何优化MySQL数据库性能以提升查询效率和系统稳定性 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
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社区 版权所有