mirror of
https://github.com/Snailclimb/JavaGuide
synced 2025-06-16 18:10:13 +08:00
修复图片链接失效问题
This commit is contained in:
parent
94021ede47
commit
569d73d5bb
@ -262,7 +262,7 @@ JConsole 是基于 JMX 的可视化监视、管理工具。可以很方便的监
|
||||
|
||||
#### 连接 Jconsole
|
||||
|
||||

|
||||

|
||||
|
||||
如果需要使用 JConsole 连接远程进程,可以在远程 Java 程序启动时加上下面这些参数:
|
||||
|
||||
@ -281,7 +281,7 @@ JConsole 是基于 JMX 的可视化监视、管理工具。可以很方便的监
|
||||
|
||||
#### 查看 Java 程序概况
|
||||
|
||||

|
||||

|
||||
|
||||
#### 内存监控
|
||||
|
||||
@ -292,7 +292,7 @@ JConsole 可以显示当前内存的详细信息。不仅包括堆内存/非堆
|
||||
> - **新生代 GC(Minor GC)**:指发生新生代的的垃圾收集动作,Minor GC 非常频繁,回收速度一般也比较快。
|
||||
> - **老年代 GC(Major GC/Full GC)**:指发生在老年代的 GC,出现了 Major GC 经常会伴随至少一次的 Minor GC(并非绝对),Major GC 的速度一般会比 Minor GC 的慢 10 倍以上。
|
||||
|
||||

|
||||

|
||||
|
||||
#### 线程监控
|
||||
|
||||
@ -300,7 +300,7 @@ JConsole 可以显示当前内存的详细信息。不仅包括堆内存/非堆
|
||||
|
||||
最下面有一个"检测死锁 (D)"按钮,点击这个按钮可以自动为你找到发生死锁的线程以及它们的详细信息 。
|
||||
|
||||

|
||||

|
||||
|
||||
### Visual VM:多合一故障处理工具
|
||||
|
||||
@ -324,6 +324,7 @@ VisualVM 提供在 Java 虚拟机 (Java Virutal Machine, JVM) 上运行的 Java
|
||||
- <https://visualvm.github.io/documentation.html>
|
||||
- <https://www.ibm.com/developerworks/cn/java/j-lo-visualvm/index.html>
|
||||
|
||||
## 公众号
|
||||
|
||||
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
|
||||
|
||||
|
@ -72,7 +72,7 @@ Java 堆是垃圾收集器管理的主要区域,因此也被称作**GC 堆(G
|
||||
|
||||
上图所示的 eden 区、s0("From") 区、s1("To") 区都属于新生代,tentired 区属于老年代。大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 s1("To"),并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 `-XX:MaxTenuringThreshold` 来设置。经过这次GC后,Eden区和"From"区已经被清空。这个时候,"From"和"To"会交换他们的角色,也就是新的"To"就是上次GC前的“From”,新的"From"就是上次GC前的"To"。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,"To"区被填满之后,会将所有对象移动到年老代中。
|
||||
|
||||

|
||||

|
||||
|
||||
### 1.1 对象优先在 eden 区分配
|
||||
|
||||
@ -193,8 +193,6 @@ JDK1.2 之前,Java 中引用的定义很传统:如果 reference 类型的数
|
||||
|
||||
JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种(引用强度逐渐减弱)
|
||||
|
||||
|
||||
|
||||
**1.强引用**
|
||||
|
||||
以前我们使用的大部分引用实际上都是强引用,这是使用最普遍的引用。如果一个对象具有强引用,那就类似于**必不可少的生活用品**,垃圾回收器绝不会回收它。当内存空 间不足,Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。
|
||||
@ -250,7 +248,7 @@ JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引
|
||||
|
||||
## 3 垃圾收集算法
|
||||
|
||||

|
||||

|
||||
|
||||
### 3.1 标记-清除算法
|
||||
|
||||
@ -284,7 +282,7 @@ JDK1.2 以后,Java 对引用的概念进行了扩充,将引用分为强引
|
||||
|
||||
## 4 垃圾收集器
|
||||
|
||||

|
||||

|
||||
|
||||
**如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。**
|
||||
|
||||
@ -301,8 +299,6 @@ Serial(串行)收集器收集器是最基本、历史最悠久的垃圾收
|
||||
|
||||
但是 Serial 收集器有没有优于其他垃圾收集器的地方呢?当然有,它**简单而高效(与其他收集器的单线程相比)**。Serial 收集器由于没有线程交互的开销,自然可以获得很高的单线程收集效率。Serial 收集器对于运行在 Client 模式下的虚拟机来说是个不错的选择。
|
||||
|
||||
|
||||
|
||||
### 4.2 ParNew 收集器
|
||||
**ParNew 收集器其实就是 Serial 收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和 Serial 收集器完全一样。**
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
类加载过程:**加载->连接->初始化**。连接过程又可分为三步:**验证->准备->解析**。
|
||||
|
||||

|
||||

|
||||
|
||||
一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的阶段,这一步我们可以去完成还可以自定义类加载器去控制字节流的获取方式(重写一个类加载器的 `loadClass()` 方法)。数组类型不通过类加载器创建,它由 Java 虚拟机直接创建。
|
||||
|
||||
@ -38,7 +38,7 @@ JVM 中内置了三个重要的 ClassLoader,除了 BootstrapClassLoader 其他
|
||||
|
||||
每一个类都有一个对应它的类加载器。系统中的 ClassLoder 在协同工作的时候会默认使用 **双亲委派模型** 。即在类加载的时候,系统会首先判断当前类是否被加载过。已经被加载的类会直接返回,否则才会尝试加载。**加载的时候,首先会把该请求委派该父类加载器的 `loadClass()` 处理,因此所有的请求最终都应该传送到顶层的启动类加载器 `BootstrapClassLoader` 中。当父类加载器无法处理时,才由自己来处理。**当父类加载器为null时,会使用启动类加载器 `BootstrapClassLoader` 作为父类加载器。
|
||||
|
||||

|
||||

|
||||
|
||||
每个类加载都有一个父类加载器,我们通过下面的程序来验证。
|
||||
|
||||
|
@ -17,7 +17,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
|
||||
|
||||
系统加载 Class 类型的文件主要三步:**加载->连接->初始化**。连接过程又可分为三步:**验证->准备->解析**。
|
||||
|
||||

|
||||

|
||||
|
||||
## 加载
|
||||
|
||||
@ -37,7 +37,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
|
||||
|
||||
## 验证
|
||||
|
||||

|
||||

|
||||
|
||||
## 准备
|
||||
|
||||
@ -48,7 +48,7 @@ Class 文件需要加载到虚拟机中之后才能运行和使用,那么虚
|
||||
|
||||
**基本数据类型的零值:**
|
||||
|
||||

|
||||

|
||||
|
||||
## 解析
|
||||
|
||||
|
@ -58,7 +58,7 @@ ClassFile {
|
||||
|
||||
**Class文件字节码结构组织示意图** (之前在网上保存的,非常不错,原出处不明):
|
||||
|
||||

|
||||

|
||||
|
||||
### 2.1 魔数
|
||||
|
||||
@ -123,7 +123,7 @@ ClassFile {
|
||||
|
||||
类访问和属性修饰符:
|
||||
|
||||

|
||||

|
||||
|
||||
我们定义了一个 Employee 类
|
||||
|
||||
@ -136,7 +136,7 @@ public class Employee {
|
||||
|
||||
通过`javap -v class类名` 指令来看一下类的访问标志。
|
||||
|
||||

|
||||

|
||||
|
||||
### 2.5 当前类索引,父类索引与接口索引集合
|
||||
|
||||
@ -162,7 +162,7 @@ public class Employee {
|
||||
|
||||
**field info(字段表) 的结构:**
|
||||
|
||||

|
||||

|
||||
|
||||
- **access_flags:** 字段的作用域(`public` ,`private`,`protected`修饰符),是实例变量还是类变量(`static`修饰符),可否被序列化(transient 修饰符),可变性(final),可见性(volatile 修饰符,是否强制从主内存读写)。
|
||||
- **name_index:** 对常量池的引用,表示的字段的名称;
|
||||
@ -174,7 +174,7 @@ public class Employee {
|
||||
|
||||
**字段的 access_flags 的取值:**
|
||||
|
||||

|
||||

|
||||
|
||||
### 2.7 方法表集合
|
||||
|
||||
@ -189,11 +189,11 @@ Class 文件存储格式中对方法的描述与对字段的描述几乎采用
|
||||
|
||||
**method_info(方法表的) 结构:**
|
||||
|
||||

|
||||

|
||||
|
||||
**方法表的 access_flag 取值:**
|
||||
|
||||

|
||||

|
||||
|
||||
注意:因为`volatile`修饰符和`transient`修饰符不可以修饰方法,所以方法表的访问标志中没有这两个对应的标志,但是增加了`synchronized`、`native`、`abstract`等关键字修饰方法,所以也就多了这些关键字对应的标志。
|
||||
|
||||
|
@ -291,7 +291,7 @@ HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说
|
||||
|
||||
最常用的就是利用 URL 重写把 Session ID 直接附加在URL路径的后面。
|
||||
|
||||

|
||||

|
||||
|
||||
## 十 Cookie的作用是什么?和Session有什么区别?
|
||||
|
||||
|
@ -30,7 +30,7 @@ Design Patterns(设计模式) 表示面向对象软件开发中最好的计算
|
||||
|
||||
**IoC(Inversion of Control,控制翻转)** 是Spring 中一个非常非常重要的概念,它不是什么技术,而是一种解耦的设计思想。它的主要目的是借助于“第三方”(Spring 中的 IOC 容器) 实现具有依赖关系的对象之间的解耦(IOC容易管理对象,你只管使用即可),从而降低代码之间的耦合度。**IOC 是一个原则,而不是一个模式,以下模式(但不限于)实现了IoC原则。**
|
||||
|
||||

|
||||

|
||||
|
||||
**Spring IOC 容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。** IOC 容器负责创建对象,将对象连接在一起,配置这些对象,并从创建中处理这些对象的整个生命周期,直到它们被完全销毁。
|
||||
|
||||
@ -134,7 +134,7 @@ AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无
|
||||
|
||||
**Spring AOP 就是基于动态代理的**,如果要代理的对象,实现了某个接口,那么Spring AOP会使用**JDK Proxy**,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用**Cglib** ,这时候Spring AOP会使用 **Cglib** 生成一个被代理对象的子类来作为代理,如下图所示:
|
||||
|
||||

|
||||

|
||||
|
||||
当然你也可以使用 AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。
|
||||
|
||||
@ -206,7 +206,7 @@ Spring 中默认存在以下事件,他们都是对 `ApplicationContextEvent`
|
||||
- `ContextRefreshedEvent`:`ApplicationContext` 初始化或刷新完成后触发的事件;
|
||||
- `ContextClosedEvent`:`ApplicationContext` 关闭后触发的事件。
|
||||
|
||||

|
||||

|
||||
|
||||
#### 事件监听者角色
|
||||
|
||||
@ -323,7 +323,7 @@ if(mappedHandler.getHandler() instanceof MultiActionController){
|
||||
|
||||
装饰者模式可以动态地给对象添加一些额外的属性或行为。相比于使用继承,装饰者模式更加灵活。简单点儿说就是当我们需要修改原有的功能,但我们又不愿直接去修改原有的代码时,设计一个Decorator套在原有代码外面。其实在 JDK 中就有很多地方用到了装饰者模式,比如 `InputStream`家族,`InputStream` 类下有 `FileInputStream` (读取文件)、`BufferedInputStream` (增加缓存,使读取文件速度大大提升)等子类都在不修改`InputStream` 代码的情况下扩展了它的功能。
|
||||
|
||||

|
||||

|
||||
|
||||
Spring 中配置 DataSource 的时候,DataSource 可能是不同的数据库和数据源。我们能否根据客户的需求在少修改原有类的代码下动态切换不同的数据源?这个时候就要用到装饰者模式(这一点我自己还没太理解具体原理)。Spring 中用到的包装器模式在类名上含有 `Wrapper`或者 `Decorator`。这些类基本上都是动态地给一个对象添加一些额外的职责
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user