JVM系列-第10章-本地方法栈
本地方法栈Java虚拟机栈于管理Java方法的调用,而本地方法栈用于管理本地方法的调用。 本地方法栈,也是线程私有的。 允许被实现成固定或者是可动态扩展的内存大小。(在内存溢出方面是相同的) 如果线程请求分配的栈容量超过本地方法栈允许的最大容量,Java虚拟机将会抛出一个stackoverflowError 异常。 如果本地方法栈可以动态扩展,并且在尝试扩展的时候无法申请到足够的内存,或者在创建新的线程时没有足够的内存去创建对应的本地方法栈,那么Java虚拟机将会抛出一个outofMemoryError异常。 本地方法是使用C语言实现的。 它的具体做法是Native Method Stack中登记native方法,在Execution Engine 执行时加载本地方法库。 当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界。它和虚拟机拥有同样的权限。 本地方法可以通过本地方法接口来访问虚拟机内部的运行时数据区。 它甚至可以直接使用本地处理器中的寄存器 直接从本地内存的堆中分配任意数量的内存。 并不是所有的JVM都支持本地方法。因为Java虚拟机规范并 ...
网站SEO优化
查询你的网站是否被搜索引擎收录使用高级搜索 site: 来查询你的网站是否被该搜索引擎收录 在搜索框内键入 site:你的网站域名 来验证你的网站是否被收录 将你的网站提交给百度/谷歌 进入百度搜索资源平台 进入之后在用户中心里找到站点管理,点击进入 点击添加网站 使用CNAME验证 CNAME验证就是添加域名解析记录 谷歌提交网站则是访问Google Search Console,同理 将 TXT 记录添加到 网站 的 DNS 配置中 如上图 不出意外几个星期内会收录你的网站 添加sitemap站点地图sitemap站点地图可以让搜索引擎更便捷的抓取你的网站,一般为XML文件。 hexo有两个插件可以自动生成sitemap: 12npm install hexo-generator-sitemap --savenpm install hexo-generator-baidu-sitemap --save 安装完成后,进入根目录的_config.yml配置文件,添加以下代码: 12345# 自动生成sitemapsitemap: path: si ...
JVM系列-第5章-虚拟机栈
虚拟机栈虚拟机栈概述由于跨平台性的设计,Java的指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器的。 优点是跨平台,指令集小,编译器容易实现,缺点是性能下降,实现同样的功能需要更多的指令。 首先栈是运行时的单位,而堆是存储的单位 栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。 堆解决的是数据存储的问题,即数据怎么放,放哪里 Java虚拟机栈是什么Java虚拟机栈(Java Virtual Machine Stack),早期也叫Java栈。每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个的栈帧(Stack Frame),对应着一次次的Java方法调用。 是线程私有的 生命周期生命周期和线程一致,也就是线程结束了,该虚拟机栈也销毁了 作用主管Java程序的运行,它保存方法的局部变量、部分结果,并参与方法的调用和返回。 对于栈来说不存在垃圾回收问题(栈存在溢出的情况) 开发中遇到哪些异常?Java 虚拟机规范允许Java栈的大小是动态的或者是固定不变的。 如果采用固定大小的Java虚拟机栈,那每一个线程的Java虚拟机栈容量可以在线程创建的 ...
JVM系列-第4章-程序计数器
程序计数器介绍JVM中的程序计数器(Program Counter Register) JVM中的(程序计数器)PC寄存器是对物理PC寄存器的一种抽象模拟 它是一块很小的内存空间,几乎可以忽略不记。也是运行速度最快的存储区域。 在JVM规范中,每个线程都有它自己的程序计数器,是线程私有的,生命周期与线程的生命周期保持一致。 任何时间一个线程都只有一个方法在执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址;或者,如果是在执行native方法,则是未指定值(undefned)。 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。 它是唯一一个在Java虚拟机规范中没有规定任何outotMemoryError情况的区域。 作用PC寄存器用来存储指向下一条指令的地址,即将要执行的指令代码。由执行引擎读取下一条指令。 代码演示 使用PC寄存器存储字节码指令地址有什么用呢?因为CPU需要不停的切换各个线程,这时候切换回来以后, ...
JVM系列-第3章-运行时数据区概述及线程
运行时数据区概述及线程前言 类的加载-> 验证 -> 准备 -> 解析 -> 初始化 这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到我们运行时数据区 内存是非常重要的系统资源,是硬盘和CPU的中间仓库及桥梁,承载着操作系统和应用程序的实时运行;JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。不同的JVM对于内存的划分方式和管理机制存在着部分差异。 运行时数据区的完整图 Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是与线程一一对应的,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁。 灰色的为单独线程私有的,红色的为多个线程共享的。即: 每个线程:独立包括程序计数器、栈、本地栈。 线程间共享:堆、堆外内存(永久代或元空间、代码缓存) 线程线程是一个程序里的运行单元。JVM允许一个应用有多个线程并行的执行。 在Hotspot JVM里,每个线程都与操作系统的本地线程直接映射。 当一个Ja ...
JVM系列-第2章-类加载子系统
类加载子系统概述 类加载器子系统作用类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识。 ClassLoader只负责class文件的加载,至于它是否可以运行,则由Execution Engine决定。 加载的类信息存放于一块称为方法区的内存空间。除了类的信息外,方法区中还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射) 类的加载过程12345678package com.zzc.hankz.jvm;public class HelloLoader { public static void main(String[] args) { System.out.println("我已经被加载啦"); }} 加载阶段通过一个类的全限定名获取定义此类的二进制字节流 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 在内存中生成一个代表这个类的java.lang.Class对象, ...
手写mybatis第三篇
MapperXML的解析和注册使用 首先需要定义 SqlSessionFactoryBuilder 工厂建造者模式类,通过入口 IO 的方式对 XML 文件进行解析。当前我们主要以解析 SQL 部分为主,并注册映射器,串联出整个核心流程的脉络。 文件解析以后会存放到 Configuration 配置类中,接下来会看到这个配置类会被串联到整个 Mybatis 流程中,所有内容存放和读取都离不开这个类。如我们在 DefaultSqlSession 中获取 Mapper 和执行 selectOne 也同样是需要在 Configuration 配置类中进行读取操作。 SqlSessionFactoryBuilder 作为整个 Mybatis 的入口,提供建造者工厂,包装 XML 解析处理,并返回对应 SqlSessionFactory 处理类。 通过解析把 XML 信息注册到 Configuration 配置类中,再通过传递 Configuration 配置类到各个逻辑处理类里,包括 DefaultSqlSession 中,这样就可以在获取映射器和执行SQL的时候,从配置类中拿到对应的内 ...
手写mybatis第二篇
实现映射器的注册和使用一、设计鉴于我们希望把整个工程包下关于数据库操作的 DAO 接口与 Mapper 映射器关联起来,那么就需要包装一个可以扫描包路径的完成映射的注册器类。 当然我们还要把上一章节中简化的 SqlSession 进行完善,由 SqlSession 定义数据库处理接口和获取 Mapper 对象的操作,并把它交给映射器代理类进行使用。 有了 SqlSession 以后,可以把它理解成一种功能服务,有了功能服务以后还需要给这个功能服务提供一个工厂,来对外统一提供这类服务。比如我们在 Mybatis 中非常常见的操作,开启一个 SqlSession。 以包装接口提供映射器代理类为目标,补全映射器注册机 MapperRegistry,自动扫描包下接口并把每个接口类映射的代理类全部存入映射器代理的 HashMap 缓存中。 而 SqlSession、SqlSessionFactory 是在此注册映射器代理的上次层使用标准定义和对外服务提供的封装,便于用户使用。我们把使用方当成用户 经过这样的封装就就可以更加方便我们后续在框架上功能的继续扩展了,这种思想可以帮助我们解决一些业务 ...
手写mybatis第一篇
创建简单的映射器代理工厂一、前言着急和快,是最大的障碍! 慢下来,慢下来,只有慢下来,你才能看到更全的信息,才能学到更扎实的技术。而那些满足你快的短篇内容虽然有时候更抓眼球,但也容易把人在技术学习上带偏,总想着越快越好。 二、设计在设计一个ORM框架的过程中,首先要考虑怎么把用户定义的数据库操作接口,xml配置的sql语句、数据库三者联系起来。 所以可以使用代理,封装一个复杂的流程为接口对象的实现类。 首先提供一个映射器的代理实现类 MapperProxy,通过代理类包装对数据库的操作,目前我们本章节会先提供一个简单的包装,模拟对数据库的调用。 之后对 MapperProxy 代理类,提供工厂实例化操作 MapperProxyFactory#newInstance,为每个 IDAO 接口生成代理类。这块其实用到的就是一个简单工厂模式 三、实现映射器代理类 1234567891011121314151617181920212223242526272829/** * 映射器代理类 * * @author:zzc * @date: 2022/4/10 */public class Map ...
JVM系列-第1章-JVM与Java体系结构
JVM与Java体系结构 book深入理解Java虚拟机: https://zzc-sso.oss-cn-hangzhou.aliyuncs.com/bolg/JVM/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Java%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%9AJVM%E9%AB%98%E7%BA%A7%E7%89%B9%E6%80%A7%E4%B8%8E%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5%EF%BC%88%E7%AC%AC3%E7%89%88%EF%BC%89%E5%91%A8%E5%BF%97%E6%98%8E.pdf 字节码java字节码,指的是用java语言编译成的字节码; 任何能在jvm平台上执行的字节码格式都是一样的; 不同的编译器,可以编译出相同的字节码文件,字节码文件也可以在不同的JVM上运行; Java虚拟机与Java语言并没有必然的联系,它只与特定的二进制文件格式—Class文件格式所关联,Class文件中包含了Java虚拟机指令集(或者称为字节码、Bytecod ...