Skip to content

Commit 765d09f

Browse files
committed
jvm
1 parent daa6f12 commit 765d09f

File tree

3 files changed

+212
-149
lines changed

3 files changed

+212
-149
lines changed

docs/design-pattern/Proxy-Pattern.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# 代理模式
22

3-
![代理设计模式](https://refactoringguru.cn/images/patterns/content/proxy/proxy.png)
4-
5-
3+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gg0b3ynhb0j31900u0b29.jpg)
64

75
## 基本介绍
86

@@ -22,7 +20,7 @@
2220

2321
为什么要控制对于某个对象的访问呢? 举个例子: 有这样一个消耗大量系统资源的巨型对象, 你只是偶尔需要使用它, 并非总是需要。
2422

25-
![数据库查询有可能会非常缓慢](https://refactoringguru.cn/images/patterns/diagrams/proxy/problem-zh.png)
23+
![图:refactoringguru.cn](https://tva1.sinaimg.cn/large/007S8ZIlly1gg0b594jl2j30e604gdfw.jpg)
2624

2725

2826

@@ -36,7 +34,7 @@
3634

3735
代理模式建议新建一个与原服务对象接口相同的代理类, 然后更新应用以将代理对象传递给所有原始对象客户端。 代理类接收到客户端请求后会创建实际的服务对象, 并将所有工作委派给它。
3836

39-
![代理模式的解决方案](https://refactoringguru.cn/images/patterns/diagrams/proxy/solution-zh.png)
37+
![图:refactoringguru.cn](https://tva1.sinaimg.cn/large/007S8ZIlly1gg0b5d5zc6j30e604gmx8.jpg)
4038

4139
代理将自己伪装成数据库对象, 可在客户端或实际数据库对象不知情的情况下处理延迟初始化和缓存查询结果的工作。
4240

@@ -46,7 +44,7 @@
4644

4745
## 代理模式结构
4846

49-
![代理设计模式的结构](https://refactoringguru.cn/images/patterns/diagrams/proxy/structure.png)
47+
![图:refactoringguru.cn](https://tva1.sinaimg.cn/large/007S8ZIlly1gg0b5gg8kij30aa0aa3yf.jpg)
5048

5149
1. **服务接口** (Service Interface) 声明了服务接口。 代理必须遵循该接口才能伪装成服务对象。
5250
2. **服务** (Service) 类提供了一些实用的业务逻辑。
@@ -326,7 +324,7 @@ public class ProxyFactory implements MethodInterceptor {
326324

327325

328326
public Object getProxyInstance(){
329-
//工具类
327+
//工具类,类似于JDK动态代理的Proxy类
330328
Enhancer enhancer = new Enhancer();
331329
//设置父类
332330
enhancer.setSuperclass(target.getClass());

docs/java/JVM/对象的创建.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# 对象的创建
2+
3+
### 对象的创建
4+
5+
语言层面,创建对象(克隆、反序列化)通常仅仅是一个new关键字而已,但JVM遇到一条 new 指令时,首先
6+
7+
8+
9+
### 对象的内存布局
10+
11+
在 HotSpot 虚拟机中,对象在内存中存储的布局可以分为 3 块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
12+
13+
![img](https://tva1.sinaimg.cn/large/00831rSTly1gdbsqxskuaj317i0rugom.jpg)
14+
15+
#### 对象头
16+
17+
- **Mark Word**:用于存储对象自身的运行时数据,存储了对象的hashCode、GC信息、锁信息三部分。如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为 32bit 和 64bit
18+
- **Class Pointer**:类型指针,用来指向对象对应的Class对象(其对应的元数据对象)的内存地址,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。在32位系统占4字节,在64位系统中占8字节;
19+
- **Length**:如果是数组对象,还有一个保存数组长度的空间,占4个字节;
20+
21+
#### 对象实例数据
22+
23+
对象实例数据包括了对象的所有成员变量,其大小由各个成员变量的大小决定,比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节(64位系统中是8个字节)。
24+
25+
| Primitive Type | Memory Required(bytes) |
26+
| :------------- | :--------------------- |
27+
| boolean | 1 |
28+
| byte | 1 |
29+
| short | 2 |
30+
| char | 2 |
31+
| int | 4 |
32+
| float | 4 |
33+
| long | 8 |
34+
| double | 8 |
35+
36+
对于reference类型来说,在32位系统上占用4bytes, 在64位系统上占用8bytes。
37+
38+
#### 对齐填充
39+
40+
并不是必然存在的,也没有特别含义,仅仅起到占位符的作用。Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数。
41+
42+
43+
44+
### 对象的访问定位
45+
46+
Java程序需要通过栈上的引用数据来操作堆上的具体对象。对象的访问方式取决于虚拟机实现,目前主流的访问方式有**使用句柄****直接指针**两种。
47+
48+
句柄,可以理解为指向指针的指针,维护指向对象的指针变化,而对象的句柄本身不发生变化;指针,指向对象,代表对象的内存地址。
49+
50+
#### 使用句柄
51+
52+
Java堆中划分出一块内存来作为句柄池,引用中存储对象的句柄地址,而句柄中包含了对象实例数据与类型数据各自的具体地址信息。
53+
54+
![img](https://img-blog.csdn.net/20160505130804767)
55+
56+
优势:引用中存储的是稳定的句柄地址,在对象被移动(垃圾收集时移动对象是非常普遍的行为)时只会改变句柄中的实例数据指针,而引用本身不需要修改。
57+
58+
#### 直接指针
59+
60+
如果使用直接指针访问,那么Java堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,而引用中存储的直接就是对象地址。HotSpot 就是使用直接指针的方式进行对象访问的。
61+
62+
![img](https://img-blog.csdn.net/20160505130823283)
63+
64+
优势:速度更快,节省了一次指针定位的时间开销。由于对象的访问在Java中非常频繁,因此这类开销积少成多后也是非常可观的执行成本。(例如HotSpot)
65+
66+
67+
68+
69+
70+
### 对象的分配过程
71+
72+
为对象分配内存是一件非常严谨和复杂的任务,JVM 的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法和内存回收算法密切相关,所以还需要考虑 GC 执行完内存回收后是否会在内存空间中产生内存碎片。
73+
74+
1. new 的对象先放在伊甸园区,此区有大小限制
75+
2. 当伊甸园的空间填满时,程序又需要创建对象,JVM 的垃圾回收器将对伊甸园区进行垃圾回收(Minor GC),将伊甸园区中的不再被其他对象所引用的对象进行销毁。再加载新的对象放到伊甸园区
76+
3. 然后将伊甸园中的剩余对象移动到幸存者 0 区
77+
4. 如果再次触发垃圾回收,此时会重新放回幸存者 0 区,接着再去幸存者 1 区
78+
5. 什么时候才会去养老区呢? 默认是 15 次回收标记
79+
6.
80+
81+
![img](https://tva1.sinaimg.cn/large/007S8ZIlly1gg09ftaynvj31120sewux.jpg)

0 commit comments

Comments
 (0)