Java类加载器
类加载器我们写的每一个Java文件,首先通过编译器编译成class文件,然后经过类加载器加载到jdk运行时内存中生成一个class类,才会被程序使用。而类加载器就是加载字节码(.class)文件的类–java.lang.ClassLoader。
类加载器的分类Java默认设置了三个类加载器。
BootstrapClassloader
ExtClassloader
AppClassloader
BootstrapClassloader 叫做启用类加载器,用于加载JRE核心类库,使用C++实现。加载路径%JAVA_HOME%/lib下的所有类库。
ExtClassloader 扩展类加载器,加载%JAVA_HOME%/lib/ext中的所有类库。
AppClassloader 应用类加载器也叫系统类加载器System Classloader,加载%CLASSPATH%路径下的所有类库。
Java 也提供了扩展,可以让我们自己实现类加载的功能。类加载器在Java中是java.lang.ClassLoader这个类,如果要自定义类加载器,只要实现这个类,重写加载方法就好了。
在 ...
Java工具 Jstack 的使用
jstack - Prints Java thread stack traces for a Java process, core file, or remote debug server.
Jstack主要的作用是生成当前进程中所有线程的信息,也就是当前时刻JVM的线程快照,通过线程的信息我们可以定位到程序中出现长时间停顿、CPU占用率过高等问题。
线程快照中的信息是当前java虚拟机内每一条线程正在执行的方法的堆栈集合,有了堆栈信息我们就可以分析出我们的程序问题出现在哪,比如线程间死锁、外部资源请求时间过长、死循环等。
使用:
123456789101112131415161718jstack [ options ] pidjstack [ options ] executable corejstack [ options ] [ server-id@ ] remote-hostname-or-IPOPTIONS -F Force a stack dump when jstack [-l] pid does not respond. ...
ThreadLocal 内存泄露问题
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 ——百度百科
上述的意思用在java中就是存在已经没有任何引用的对象,但是GC又不能把对象所在的内存回收掉,所以就造成了内存泄漏。
ThreadLocal主要解决的是对象不能被多个线程同时访问的问题。根据ThreadLocal的源码看看它是怎么实现的。
ThreadLocal设置数据的set()方法
12345678910111213141516public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) ...
Spring Boot 打包成Jar包运行的原理
相比于传统的Java打包方式,使用SpringBoot打包插件打包成jar包后,可以直接使用java -jar 运行SpringBoot项目,本篇就来分析一下运行的原理。
SpringBoot打包插件
1234<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId></plugin>
打包完后会生成两个文件,一个***.jar和***.jar.original
.jar文件是SpringBoot打包后生成的文件,.jar.original是用原生方式打包生成的文件,对比一下两个的区别
.jar.original文件
.jar文件
.jar.original就是普通的jar打包的结构,这里主要看.jar文件的结构:
META-INFO目录:META-INFO/MANIFEST.MF里包含了jar包的元数据,包含了项目的启动类等信息.
org目录: ...
设计一个支持热加载的Java应用启动器
热加载是指在不重启服务的情况下使更改的代码生效。注意和热部署的区别,热加载主要是在开发环境下使用。
首先要知道Java程序是怎么运行起来的,Java类加载分为其7个阶段。
其中加载阶段是用户可以自定义,而验证阶段、准备阶段、解析阶段、初始化阶段都是用 JVM 来处理的。整个类加载是在Java 中一个叫做类加载器上进行的,如果我们能程序更改后,让程序所在的进程能够实时的获取到编译后的Class类字节码信息,然后重新加载的话,那么就可以实现热加载功能。
Java 类加载器类加载器,顾名思义就是加载Java类的工具,Java默认设置了三个类加载器。
BootstrapClassloader
ExtClassloader
AppClassloader
BootstrapClassloader 叫做启用类加载器,用于加载JRE核心类库,使用C++实现。加载路径%JAVA_HOME%/lib下的所有类库。
ExtClassloader 扩展类加载器,加载%JAVA_HOME%/lib/ext中的所有类库。
AppClassloader 应用类加载器也叫系统类加载器System C ...
聊一聊Tomcat 系统架构设计
总体架构Tomcat 是一个应用服务器,那么要开发一个应用服务器,首先捋一捋它的需求,要实现那些功能。
1、 首先可以和客户端建立连接,并且能够处理客户端的连接
2、 其次还要解析处理我们写的 Servlet
3、 最后能够根据客户端的请求找到相应的 Servlet。
在 Tomcat 中将这些需求分为了两大功能
处理 Socket 连接,并将网络字节流转换成 Request 对象和 Response 对象
解析、加载和管理 Servlet,处理请求并返回响应数据
Tomcat 将这两大功能,设计成了两个主要的组件
连接器(Connector)
容器(Container)
来看一下 Tomcat 的总体架构
上图中是 Tomcat 的整体架构,一个 Tomcat 代表一个 Server,一个 Server 下包含对个 Service,每个 Service 下包含多个连接器和一个容器。
Service 本身没有什么重要的作用,它只是把连接器和容器组装在一起了,但是 Tomcat 可以同时设置多个 Service,也就可以部署多个服务。比如有两个相同的项目,可以把这两个项目放到两 ...
Java泛型中的类型擦除以及Type接口
Java 泛型(generics)是JDK1.5中引入的一个新特性,其本质是参数化类型,解决不确定具体对象类型的问题;其所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
但是在Java中并不是真正的泛型,实际上是“伪泛型”
类型擦除(type Erasure)为了与之前的版本兼容,JDK1.5中通过类型擦除来增加的泛型功能。Java泛型只是在编译器层次上,在编译后生成的字节码中是不包含泛型中类型的信息的。通过一个例子来证明类型擦除
12345678public class main { public static void main(String[] args) { ArrayList<String> sList = new ArrayList<String>(); ArrayList<Integer> iList = new ArrayList<Integer>(); ...
Java函数式编程
简介什么是函数式编程函数式编程是一种编程范式,即一切都是数学函数。在Java面向对象编程中,程序是一系列相互作用(方法)的对象,而在函数式编程中,程序会是一个无状态的函数组合序列。
函数是“第一等公民”“第一等公民”指的是函数和其他数据类型一样,处于平等的地位。可以赋值给变量、可以作为另一个函数的参数或者作为一个函数的返回值。比如
12345// 将两数相加的逻辑赋值给变量sumvar sum = (a,b)->a+b;// 将函数作为另一个函数的参数operation(sum)
Java函数试编程Lambda 表达式历史上研究函数式编程的理论是Lambda演算,所以我们经常把支持函数式编程的编码风格称为Lambda表达式。
在Java中Lambda 表达式的表达形式:
1(参数)->方法体
参数:可以有多个,如果只有一个可以省略括号
->:箭头符号。
方法体:方法体超过一句时,要用{}包裹,可以根据情况看是否需要return语句
函数式接口Java 8提供了函数式编程接口的概念,用作Lambda表达式的类型。
函数式接口:只定义了单一抽象方法的接口 ...
HashMap那些事儿
HashMap 在 Java 中是一个使用高频的数据结构,JDK1.8 以后 HashMap 进行了一次翻天覆地的改变。
本文基于 JDK1.8 分析一下 HashMap
存储结构转换在 JDK1.8 以前 HashMap 采用的是数组+链表的结构,JDK1.8 以后又引入了红黑树的结构,会在链接和红黑树之间转换,结合源码分析一下 HashMap 对数组+链表和数组+红黑树的转换首先看一下数据的存储结构
1transient HashMap.Node<K, V>[] table;
HashMap 定义了一个 Node 的数组,Node 的定义
1234567 static class Node<K, V> implements Entry<K, V> { final int hash; final K key; V value; HashMap.Node<K, V> next; // ....省略}
Node 中包含了四个属性hash、key、value、next。 ...
TCP三次握手和四次挥手
定义:TCP(Transmission Control Protocol:传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议.
TCP在发送数据前,会在通信双方之间建立一条连接。通过这条连接,客户端和服务端可以保存一份对方的信息,如ip地址、端口号等。通信双方的数据传输就是在这条连接上进行的。这条连接的建立和断开的过程就是所谓的三次握手和四次挥手
TCP报文头部数据在了解三次握手和四次挥手之前,先来了解一下TCP报文的头部数据结构上图中有几个字段是在三次握手和四次挥手需要的
Sequence number(seq):序列号 32位
Acknowledgment number(ack): 确认序列号 32位
SYN、ACK、FIN标志位
SYN : 建立起一个新的连接
ACK : 确认号有效
FIN : 释放一个连接
注意: 不要将ack和ACK理解混了,ack是一串序列号,ACK是一个标志位。当ACK为1时,代表ack序列号有效
三次握手三次握手是TCP建立连接的过程。主要作用是判断通信双方有没有传输数据的能力。看一下整个握手的过程。
三次握手步骤:
第一 ...