JVM直接内存
😀 这里写文章的前言:一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 直接内存操作系统的本地内存,就是真正的内存.而不是像JVM虚拟化的内存
优点: 更快,因为不像JVM堆、栈内存,需要先虚拟化一层,再做操作.直接内存是直接使用的.
缺点:需要人工释放
使用案例1. Java可以通过Unsafe类去操作本地内存
Netty、ByteBuffer底层操作系统mallcoc函数
JNI (native本地方法)
JNA,本质就是对JNI的包装
为什么使用直接内存优点
减少垃圾回收次数, 不会STW;减少内存碎片化,提高内存利用率
加快操作速度, 减少了堆与直接内存的复制环节,直接省略了这一环节
多个JVM的话,共享很麻烦, 但是直接内存共享更简单.
不受制于虚拟化的控制,比如搞个1TB内存,堆可能根本不够.直接内存直接加就可以了
缺点
不受JVM控制,需要自己手动释放,如果忘记了,会发生内存泄露,而且是直接内存泄露,
**不好排查问题.**因为直接内存和内核关联大,和 ...
JVM内存结构
😀 这里写文章的前言:一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么?并简述你给出的答案。
可以说说你的故事:阻碍、努力、结果成果,意外与转折。
📝 主旨
📔 程序计数器
唯一一个无OOM的地方,类比操作系统中的 PC
记录正在执行的虚拟机字节码指令的行号(如果正在执行的是本地方法则为空)
CPU是轮转分片执行的, 为了防止CPU切换的时候返回忘记之前执行到哪一步,需要程序计数器来记录走到具体哪一行指令了(依赖指令前的序号定位)
class文件会看到一串增序的数字就是指令执行的顺序,这一串增序可能不是连续的,比如下面1-3之间的2消失了,因为机器本身要执行其他的操作,这部分操作是不希望你看到的,可能和安全有关系就没展示了.(计算机硬件封装的操作没必要全部给你展示)
为什么被设定为私有的
因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行,如果是共享的话,就混乱了不好辨别
📔 Java 虚拟机栈栈是解决程序的运行问题,即程序如何执行,或者说程序如何处理数据 (顺序是: 先进后出)
方法在执行的同时会创建一个栈帧用于 ...
SpringBoot动态添加接口
背景最近看了公司的产品,有一个这样的动态,就是根据input输入的内容,进行动态接口的添加.
比如 我在没有添加之前,访问 http://localhost:8080/test 该地址是404, 于是通过input的输入创建,就相当于动态添加了一个接口,于是就可以访问了.
实现的方式有很多种, 具体的想要的效果肯定是需要根据自己的业务角度来.
实现思路这里是说下个人的实现思路 :
方案一 : 先定义好类,然后使用反射根据定义的类,创建好一个对象出来,然后将这个对象给注入到Spring容器中来,这里不仅仅是注入进来这么简单,还是需要经过 MVC(也就是Controller等注解的匹配操作)来实现
方案二 : 基于请求404的拦截来现实. 比如你新添加的接口访问肯定是404,于是我们可以定义一个拦截,然后获取出请求的路径,根据提前定好的一些设置,进行逻辑的处理.
这里肯定还会有很多好的实现思路,并且基于每个框架都是不一样的,这里更多的是基于 SpringBoot框架来实现这个思路的.
代码实现基于反射创建bean注入代码实现定义一个类的模板
public String template ...
spring的refresh方法阅读
前言这里是相对上一次再次的阅读和记录,比上次有了更深入的理解.
这里是再次整理的阅读 Spring 的源码, 相对比上次的阅读,我希望这次可以更清晰&更深刻的理解Spring,也不仅仅会从一个案例来进行分析,会结合多方面的知识来进行整理分析.
这里放上之前阅读的比例 : https://github.com/baoyang23/source-notes/tree/master/java/spring_bean
该目录下面有 : bean/get/extend 三个主要地方的分析.
此模块还是讲述 整体的 flow,后面会对单个进行分析&Spring提供怎么样的扩展方式来进行增强扩展等.
案例入门操作的话,可以参考之前的博客.
分析 这里我们先不忙这其他类型的bean分析, 就对我们作为 config 的 bean 进行分析. 先单个分析容易理解些.
入口类 :
public class InitWorkFlowSpring { public static void main(String[] args) { ...
spring初始化(三)
题记 前面讲到了这么多的什么BeanPostProcessor,事件什么的. 如果不写几下代码这里怕是很难弄清楚是个怎么回事. 所以只有看到代码跑,就大致可以看到其效果还是很明显的.
BeanDefinitionRegistryPostProcessor 先写一个类简单实现下 BeanDefinitionRegistryPostProcessor 这个接口 :
运行后的结果是可以很明显的看到我们的打印数据输出结果的.
程序是怎么运行到这个地方来的呢?
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>) 走到这个方 ...
spring初始化(二)
题记 昨天记录了this()和 register() 这二个方法, 这二个方法都是为后面的做铺垫,也就是提前初始化了一些环境和读取class文件. refresh() 这个方法才是最重要的,其中包含的内容是非常多的. 所以这里慢慢进行更新其方法的内容.
refresh 方法这里可以看到的是, refresh()该方法里面,基本都是走了很多方法的. 所以挨个看方法,有些方法是留给子类的,也就是进行扩展的. 从synchronized这个关键字来看,这里只容许一次只有一个线程来执行这个方法.
@Overridepublic void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal ...
spring初始化(一)
阅读方法最简单的阅读方法,就是创建一个maven项目,让引入Spring的依赖. 然后写上一个main方法,来读取包下的内容,然后写一个bean,即可. 这个bean要在你扫描的包下. 于是我们直接在new的地方打上断点跟进去即可.
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.0.RELEASE</version> </dependency></dependencies>public class SpringStartMain { public static void main(String[] args) { AnnotationConfigApplicationContext c ...
PriorityQueue源码阅读记录
PriorityQueue : 中文是优先队列 , 队列的特点就是数据 先进先出, 但是这个优先队列的特别是什么呢? 首先肯定是有队列的基本特点,也就是有先进先出。 如果是先进先出的话,那么就和普通的有什么区别?优先二字又是体现在什么地方呢? 优先级队列的元素按照其自然顺序进行排序, 或者根据 构造队列时提供的 Comparator 进行排序.
结构 结构就是 PriorityQueue这个类的 全局变量参数, 因为这些参数是存储数据的, 所以只要理解了这些参数,就明白了这个 PriorityQueue这个是对数据是怎么样进行存储的, 还是比较好理解的.
这里可以看到 priorityQueue的数据结构还是很简单的, 一眼扫过去没什么需要特别的理解
// 存储数据的数组transient Object[] queue;// 记录 priorityQueue的长度private int size = 0;// 这个就是之前说提到的 可以根据 Comparator 进行排序private final Comparator<? super E> comparator;
...
spring创建bean_one
前提我们在创建 Spring Bean 的时候,是可以通过很多种方式来创建的. 但是这么多种方式,又是怎么加载的?是不是又有顺序呢? 所以对 Spring 的 Bean 创建还是很有必要的.
创建方式我们可以通过自己创建 bd , 然后调用 registerBeanDefinition 方法给注册到 Spring 中来.
那么创建bd的怎么创建的呢?可以看到下面的二种创建方式.
这是通过 bd 来的.
public class BeanDefinitionCreateAndRegister { public static void main(String[] args) { // 1 : 通过 BeanDefinitionBuilder 来创建 bd BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(Person.class); beanDefinitionBuilder.addProper ...
ArrayDeque源码阅读记录
ArrayDeque 在我目前做的项目中,使用是比较少的,基本都没有地方用到。可能是我太low了,也可能是业务没有一定要用到队列的情况. 但是这不影响我们对其进行源码阅读。
结构结构还是可以看到, 使用一个Object的数组, 二个int类型的变量来记录头和尾(从单词的意思)
transient Object[] elements; // non-private to simplify nested class accesstransient int head;transient int tail;
方法
构造函数
无参构造函数. 可以看到无参构造函数,默认是对数据进行初始化大小为16的操作.
public ArrayDeque() { elements = new Object[16];}
有参构造函数
/**传递int类型的构造函数,最后是调用到了calculateSize方法返回值来初始化数组大小 */public ArrayDeque(int numElements) { allocateElements(numElements ...



