Java
2021-10-21 13:55:45 0 举报
AI智能生成
后端开发
作者其他创作
大纲/内容
加载
验证
准备
解析
初始化
加载过程
BootstrapClassLoader 启动类加载器
ExtensionClassLoader 扩展类加载器
ApplicationClassLoader 应用程序类加载器 (也称 系统类加载器)
类加载器
好处
双亲委派模型
类加载机制
Xss
JVM参数
runnable
jstack
jstat(JVM Statistics Monitoring Tool)
分析工具
newCachedThreadPool
newFixedThreadPool
newSingleThreadExecutor
NewScheduledThreadPool
线程池
保证线程安全,无需同步。不可变对象可以被自由地共享
如果字符串是可变的,那么会引起很严重的安全问题。譬如,数据库的用户名、密码都是以字符串的形式传入来获得数据库的连接,或者在socket编程中,主机名和端口都是以字符串的形式传入。因为字符串是不可变的,所以它的值是不可改变的,否则黑客们可以钻到空子,改变字符串指向的对象的值,造成安全漏洞。
类加载器要用到字符串,不可变性提供了安全性,以便正确的类被加载。
因为字符串是不可变的,所以在它创建的时候hashcode就被缓存了,不需要重新计算。
通过反射可破坏其可变性: String str = "123"; System.out.println(str); Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[]) field.get(str); value[1] = '3'; System.out.println(str);
Immutable 不可变性
string
为其他对象提供一种代理以控制对这个对象的访问
提供统一接口,在不影响系统调用的情况下进行扩展,即遵循开放封闭原则
被代理类不能有final修饰符,否则报错
被代理方法不能有final修饰符,否则代理无效
cglib
jdk
动态代理
静态代理
代理类型
代理模式
对象的统一托管
规范生命周期
灵活的依赖注入
一致的获取对象方式(默认单例)
优势
IOC
core
context
aop
expression
orm
1. 用户请求发送至DispatchServlet
2. DispatcherServlet收到请求调用HandlerMapping处理
3. HandlerMapping找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及拦截器(如果有则生成)一并返回给DispatcherServlet
4. DispatcherServlet调用HandlerAdapter处理
5. HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)
6. Controller执行完成返回ModelAndView
7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9. ViewReslover解析后返回具体View
mvc
dao
重要模块
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
AnnotationConfigApplicationContext
分支主题
ApplicationContext
@Transactional
singleton
prototype
request
session
application
websocket
生命周期
1. 首先执行BeanPostProcessor中的postProcessBeforeInitialization
2. 执行InitializingBean接口中的afterPropertiesSet方法
3. 再执行xml配置中的 init-method方法
4. 最后执行BeanPostProcessor中的postProcessAfterInitialization
创建流程
bean
bean非线程安全。对于每个bean的线程安全问题,根本原因是每个bean自身的设计。不要在bean中声明任何有状态的实例变量或类变量,如果必须如此,那么就使用ThreadLocal把变量变为线程私有的,如果bean的实例变量或类变量需要在多个线程之间共享,那么就只能使用synchronized、lock、CAS等这些实现线程同步的方法了。
Spring
SpringBootConfiguration
EnableAutoConfiguration
ComponentScan
核心注解 @SpringBootApplication
SpringBoot
框架
SimpleDateFormat
常见线程安全问题
虽然Entry是弱引用,里面的key在gc发生时会被回收,但是对应的value还是会造成内存泄露
ThreadLocal
常见内存泄露类型
强引用
软引用
弱引用
虚引用
引用类型
仅有弱引用指向的对象,只要发生gc就会被回收
仅有软引用指向的对象,只有发生gc且内存不足,才会被回收
普通的引用,强引用指向的对象不会被回收
1. 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
2. 禁止进行指令重排序。
volatile
synchronized
并发
(1).volatile 仅能使用在变量级别;synchronized 则可以 使用在变量、方法、代码块和类级别的(2).volatile 仅能实现变量的修改可见性,并不能保证原子性; synchronized 则可以保证变量的修改可见性和原子性(3).volatile 不会造成线程的阻塞;synchronized 可能 会造成线程的阻塞。(4).volatile 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化
在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性
反射
在等待时wait 会释放锁,而sleep 一直持有锁。wait 通常被用于线程间交互,sleep 通常被用于暂停执行
wait与sleep
实例方法thread.isInterrupted() 与 静态方法Thread.interrupted()
中断协议
wait
sleep
join
可响应中断线程
InterruptedException 当你使用sleep这些方式时,java会从语法级别强制你使用try...cacth...语句接收InterruptedException,即阻塞中的线程如果收到中断信号,会通抛出InterruptedException异常将具体响应处理转移给开发者,同时把中断状态置为true
InputStream
OutputStream
不可响应中断线程
interrupt ( )
线程
Error
NullPointerException
ArrayIndexOutOfBoundsException
IndexOutOfBoundsException
ArithmeticException
ClassNotFoundException
IllegalAccessException
IllegalArgumentException
IllegalStateException
RuntimeException
受检异常
IOException
SQLException
InterruptedException
IllegalAccessException
ClassNotFoundException
NoSuchMetodException
非运行时异常
非受检异常
Exception
throwable
异常
引用计数法
可达性分析算法
判断对象是否存活的算法
效率问题,标记和清除两个过程的效率都不高
空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
标记清除算法
复制算法
标记整理算法
分代收集算法
垃圾收集算法
serial
parnew (Serial收集器的多线程版本)
parallel scavenge
serial old
parallel old
cms
G1
垃圾收集器
MaxPermSize设置过小(默认为4M)
tomcat热部署时没有清理之前加载的环境
引用了大量三方jar包
可能的原因
将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的
改进
在 JDK 1.8 中, HotSpot 已经没有 “PermGen space”这个区间了,取而代之是一个叫做 Metaspace(元空间) 的东西。
java.lang.OutOfMemoryError: PermGen space
移除永久代的工作从JDK1.7就开始了。JDK1.7中,存储在永久代的部分数据就已经转移到了Java Heap或者是 Native Heap。但永久代仍存在于JDK1.7中,并没完全移除,譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap
存在递归调用
存在循环依赖
原因
尽量将递归调用铺平,减少栈深度
如果你确认递归实现是正确的,为了允许大量的调用,你可以增加栈的大小。依赖于安装的 Java 虚拟机,默认的线程栈大小可能是 512KB 或者 1MB。你可以使用 -Xss 标识来增加线程栈的大小。这个标识即可以通过项目的配置也可以通过命令行来指定
StackOverFlowError
java.lang.OutOfMemoryError: java heap space
java.lang.OutOfMemoryError: unable to create native thread
内存溢出分析
GC
SimpleExecutor
ReuseExecutor
BatchExecutor
Executor
延迟加载
ParameterHandler
ResultSetHandler
StatementHandler
支持的四种接口
插件运行原理
Mybatis
ORM
线程逃逸
方法逃逸
栈上分配
同步消除
标量替换
高效优化
逃逸分析
ReentrantLock
可重入锁
1. ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。2. ReentrantLock还提供了条件Condition,对线程的等待、唤醒操作更加详细和灵活,所以在多个条件变量和高度竞争锁的地方,ReentrantLock更加适合3. ReentrantLock支持可中断处理4. ReentrantLock提供了一个Condition(条件)类,用来实现唤醒与当前锁相关联的线程,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程,粒度更细,效率更高。
不可重如锁
锁
集合
1.构造器
init()
service()
destroy()
doGet
doPost
doHead
doDelete
doPut
doOptions
doTrace
HttpServlet
实现
Servlet
Java
0 条评论
回复 删除
下一页