- 博客(20)
- 收藏
- 关注
原创 Netty权威指南笔记——下
该层的主要职责就是监听网络的读写和连接操作,负责将网络层的数据读取到内存缓冲区中,然后触发各种网络事件,例如连接创建、连接激活、读事件、写事件等,将这些事件触发到PipeLine中,由PipeLine管理的职责链来进行后续的处理。当令牌桶有足够的令牌时,再均匀的向外发送这些被缓存的报文。2. 写空闲,链路持续时间t没有发送任何消息;用户线程实现(UT),通常情况下,用户线程指的是完全建立在用户空间线程库上的线程,用户线程的创建、启动、运行、销毁和切换完全在用户态中完成,不需要内核的帮助,因此执行性能更高。
2024-08-05 00:41:28
791
原创 Netty权威指南笔记——中
但是,通过调整NIO线程池的线程参数,可以同时启动多个串行化的线程并行运行,这种局部无锁化的串行线程设计相比一个队列一多个于作线程的模刑性能面优。网络I/O操作——读、写等由一个NIO线程池负责,线程池可以采用标准的JDK线程池实现,它包含一个任务队列和N个可用的线程,由这些 NIO 线程负责消息的读取、解码、编码和发送。如果业务逻辑处理复杂,不要在NIO线程上完成,建议将解码后的POJO消息封装成Task,派发到业务线程池中由业务线程执行,以保证NIO线程尽快被释放,处理其他的I/O操作。
2024-08-05 00:38:27
1937
原创 Netty权威指南笔记——上
Linux的内核将所有外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor(fd,文件描述符)。而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符),描述符就是一个数字,它指向内核中的一个结构体(文件路径,数据区等一些属性)。根据UNIX网络编程对I/O模型的分类,UNIX提供了5种I/O模型,分别如下。(1) 阻塞I/O模型:最常用的1/0模型就是阻塞I/O模型。
2024-08-05 00:32:38
1891
原创 Chapter 12&13-高效并发
对于64位的数据类型(long和double),允许虚拟机将没有被volatile修饰的64位数据的读写操作划分为两次32位的操作来进行,即允许虚拟机实现自行选择是否要保证64位数据类型的load、store、read和write这四个操作的原子性,这就是所谓的“long和double的非原子性协定”(Non-Atomic Treatment of double and long Variables)。当你的数据需要在不同代码块间共享,但这些代码块总是在同一线程中运行时,可以使用线程本地存储。
2024-08-05 00:23:05
880
原创 Chapter 8-虚拟机字节码执行引擎
8.1 概述 虚拟机的执行引擎则是由软件自行实现的,因此可以不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。通常会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择。 8.2 运行时栈帧结构 Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,每一个方法从调用开始至执行结束的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程。 每一个栈帧都
2024-08-05 00:17:25
561
原创 Chapter 7-虚拟机类加载机制
7.1 概述 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程被称作虚拟机的类加载机制。 类型的加载、连接和初始化过程都是在程序运行期间完成。运行期动态加载和动态连接这个特点,使其具有动态扩展的语言特性。 7.2 类加载的时机 类的生命周期:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使
2024-08-05 00:14:24
922
原创 Chapter 6-类文件结构
6.1 概述 计算机只能识别0和1,但由于最近虚拟机以及大量建立在虚拟机之上的程序语言出现,把程序编译成二进制本地机器码(Native Code)已不再是唯一的选择,越来越多的程序语言选择了与操作系统和机器指令集无关的、平台中立的格式作为程序编译后的存储格式。 6.2 无关性的基石 字节码(Byte Code)是构成平台无关性的基石,而实现语言无关性的基础仍然是虚拟机和字节码存储格式。Java虚拟机不与包括Java语言在内的任何程序语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联。
2024-08-05 00:12:32
352
原创 Chapter3-垃圾收集器与内存分配策略
3.1 概述 垃圾收集(Garbage Collection)关注三件事:1. 哪些内存需要回收?2. 什么时候回收?3. 如何回收? 程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭,不需要考虑回收 而Java堆和方法区两个区域有着很显著的不确定性:只有处于运行期间,我们才能知道程序究竟会创建哪些对象,这部分内存的分配和回收是动态的。垃圾收集器所关注的正是这部分内存该如何管理。 3.2 对象已死? 3.2.1 引用计数算法 在对象中添加一个引用计数器,每当有一个地方引用它时
2024-08-05 00:10:02
724
原创 Chapter2-Java内存区域与内存溢出异常
2.1 概述 由于Java虚拟机拥有自动内存管理机制,不易出现内存泄漏和内存溢出。然而,正因如此,需要了解虚拟机是怎样使用内存的,才能排查错误、修正问题。 2.2 运行时数据区域 Java虚拟机在执行Java程序时会把它所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途,以及创建和销毁的时间。 2.21 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的
2024-08-05 00:06:56
669
原创 MySQL查询性能优化
减少重复计算:在一个复杂的查询中,某个值如果需要在多个地方使用,通常情况下可能需要重复计算这个值。通过将这个值存储在一个用户自定义变量中,可以避免重复计算,从而减少查询的总体资源消耗。编写偷懒的UNION:假设需要编写一个UNION查询,其第一个子查询作为分支条件先执行,如果找到了匹配的行,则跳过第二个分支。在某些业务场景中确实会有这样的需求,比如先在一个频繁访问的表中查找“热”数据,找不到再去另外一个较少访问的表中查找“冷”数据。(区分热数据和冷数据是一个很好的提高缓存命中率的办法)。
2024-08-01 02:12:17
621
原创 Reids笔记——单机数据库的实现
Redis服务器默认会创建16个数据库。默认情况下,Redis客户端的目标数据库为0号数据库。客户端可以通过执行SELECT命令来切换目标数据库。
2024-08-01 02:09:34
640
原创 Redis——多机数据库的实现
在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为,而对主服务器进行复制的服务器则被称为。
2024-08-01 02:04:09
454
原创 JUC——线程安全集合类概述
Java 8数组(Node) +( 链表 Node | 红黑树 TreeNode ) 以下数组简称(table),链表简称(bin)初始化,使用 cas 来保证并发安全,懒惰初始化 table树化,当 table.length < 64 时,先尝试扩容,超过 64 时,并且 bin.length > 8 时,会将链表树化,树化过程 会用 synchronized 锁住链表头put,如果该 bin 尚未创建,只需要使用 cas 创建 bin;
2024-08-01 01:55:16
887
原创 JUC——共享模型之工具
这时 Thread-4 释放了 permits,接下来 Thread-0 竞争成功,permits 再次设置为 0,设置自己为 head 节点,断开原来的 head 节点,unpark 接 下来的 Thread-3 节点,但由于 permits 是 0,因此 Thread-3 在尝试不成功后再次进入 park 状态。,是阻塞式锁和相关的同步器工具的框架。提交任务的时,即使有线程池里的线程从阻塞队列中获取不到任务,如果线程池里的线程数还是小于核心线程数,那么依然会继续创建线程,而不是复用已有的线程。
2024-08-01 01:48:29
792
原创 JUC——共享模型之内存与无锁
如果 t 线程程频繁从主内存中读取 run 的值,JIT 编译器会将主存中run的值缓存至自己工作内存中的高速缓存中,减少对主存的访问,提高效率。volatile关键字可以用来修饰成员变量和静态成员变量,避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作 volatile 变量都是直接操作主存,保证了。ABA问题:如果在CAS操作执行之前,共享变量的值被改变了多次,且最终又恢复为原始值,那么CAS操作可能会误以为共享变量的值没有发生变化,导致数据的不一致。类来解决 ABA 问题。
2024-08-01 01:34:11
764
原创 JUC——共享模型之管程
内置锁在Java中被抽象为监视器锁(monitor),每个 Java 对象都可以关联一个 Monitor 对象,如果使用 synchronized 给对象上锁(重量级)之后,该对象头的 Mark Word 中就被设置指向 Monitor 对象的指针。例如,t1线程已经获得A对象锁,想获取 B对象的锁,而t2线程已经获得B对象锁,想获取A对象的锁。如果在尝试加轻量级锁的过程中,CAS 操作无法成功,这时就是有其它线程为此对象加上了轻量级锁(有竞争),需要进行锁膨胀,将轻量级锁变为重量级锁。
2024-08-01 01:29:30
1008
原创 JUC——进程与线程
【阻塞状态】 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入 【阻塞状态】 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们。有一种特殊的线程叫做守护线程,只要其它非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。单核虽然不能通过多线程提高效率,但可以让不同的线程轮流使用CPU ,避免被一个线程长时间占用。
2024-08-01 01:13:43
1804
原创 Redis笔记——数据结构与对象
Redis没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。Redis只会使用C字符串作为字面量,在大多数情况下,Redis使用SDS作为字符串表示。当Redis需要的不仅仅是一个字符串字面量,而是一个可以被修改的字符串值时,Redis就会使用SDS来表示字符串值,比如在Redis的数据库里面,包含字符串值的键值对在底层都是由SDS实现的。
2024-07-31 07:29:27
724
原创 高性能MySQL笔记
MySQL喜欢简单的原则:尽量避免过度设计,例如会导致极其复杂查询的schema设计,或者有很多列的表设计。使用小而简单的合适数据类型,除非真实数据模型中有确切的需要,否则应该尽可能地避免使用NULL值。尽量使用相同的数据类型存储相似或相关的值,尤其是要在关联条件中使用的列。注意可变长字符串,其在临时表和排序时可能导致悲观的按最大长度分配内存。尽量使用整型定义标识列。小心使用ENUM和SET。虽然它们用起来很方便,但是不要滥用。最好避免使用BIT。
2024-07-31 06:19:57
783
原创 关于leecode70.爬楼梯
今天在做这道题时想到用排列组合的方式求,但由于需要使用阶乘,导致在n>22的时候出现了结果不正确,但是没有报错,应为long字段溢出,因为21!=51090942171709440000,而java中Long的最大值为9223372036854775807,记录一下这个错误class Solution { public int climbStairs(int n) { int p=n/2; //最多可以有几个2 int a=p-1; //C(b,a).
2021-08-19 10:48:52
86
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人