├── .github ├── ISSUE_TEMPLATE └── PULL_REQUEST_TEMPLATE ├── .travis.yml ├── 79884.log ├── LICENSE ├── MD ├── ArrayList.md ├── Cache-design.md ├── ClassLoad.md ├── ConcurrentHashMap.md ├── Consistent-Hash.md ├── DB-split.md ├── GarbageCollection.md ├── HashMap.md ├── ID-generator.md ├── Java-lock.md ├── Limiting.md ├── LinkedList.md ├── MemoryAllocation.md ├── MySQL-Index.md ├── OOM-analysis.md ├── ReentrantLock.md ├── SQL-optimization.md ├── Spike.md ├── SpringAOP.md ├── Synchronize.md ├── TCP-IP.md ├── Thread-common-problem.md ├── ThreadPoolExecutor.md ├── Threadcore.md ├── collection │ ├── HashSet.md │ └── LinkedHashMap.md ├── concurrent │ ├── thread-communication.md │ └── volatile.md ├── newObject.md └── spring │ └── spring-bean-lifecycle.md ├── README.md ├── java_pid26365.hprof ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── crossoverjie │ │ ├── Application.java │ │ ├── actual │ │ ├── LRUAbstractMap.java │ │ ├── LRULinkedMap.java │ │ ├── LRUMap.java │ │ ├── ReadFile.java │ │ ├── ThreadCommunication.java │ │ ├── TwoThread.java │ │ └── TwoThreadWaitNotify.java │ │ ├── algorithm │ │ ├── BinaryNode.java │ │ ├── HappyNum.java │ │ ├── LinkLoop.java │ │ ├── MergeTwoSortedLists.java │ │ ├── ReverseNode.java │ │ ├── TwoArray.java │ │ ├── TwoStackQueue.java │ │ └── TwoSum.java │ │ ├── basic │ │ ├── HashMapTest.java │ │ └── StringTest.java │ │ ├── classloader │ │ ├── ChildClass.java │ │ ├── Main.java │ │ └── SuperClass.java │ │ ├── concurrent │ │ ├── Singleton.java │ │ ├── StopThread.java │ │ ├── ThreadState.java │ │ ├── Volatile.java │ │ └── VolatileInc.java │ │ ├── design │ │ └── pattern │ │ │ └── factorymethod │ │ │ ├── Animal.java │ │ │ ├── AnimalFactory.java │ │ │ ├── Cat.java │ │ │ ├── CatFactory.java │ │ │ ├── Fish.java │ │ │ ├── FishFactory.java │ │ │ └── Main.java │ │ ├── gc │ │ └── MinorGC.java │ │ ├── guava │ │ └── CacheLoaderTest.java │ │ ├── oom │ │ └── heap │ │ │ ├── HeapOOM.java │ │ │ └── MetaSpaceOOM.java │ │ ├── proxy │ │ ├── cglib │ │ │ ├── RealSubject.java │ │ │ └── RealSubjectIntercept.java │ │ └── jdk │ │ │ ├── CustomizeHandle.java │ │ │ ├── ISubject.java │ │ │ └── impl │ │ │ └── ISubjectImpl.java │ │ ├── red │ │ └── RedPacket.java │ │ ├── spring │ │ ├── LifeCycleConfig.java │ │ ├── SpringLifeCycle.java │ │ ├── annotation │ │ │ └── AnnotationBean.java │ │ ├── aware │ │ │ └── SpringLifeCycleAware.java │ │ ├── processor │ │ │ └── SpringLifeCycleProcessor.java │ │ └── service │ │ │ └── SpringLifeCycleService.java │ │ └── synchronize │ │ └── Synchronize.java └── resources │ ├── application.properties │ └── logback.xml └── test └── java └── com └── crossoverjie ├── actual ├── AbstractMapTest.java ├── LRULinkedMapTest.java └── LRUMapTest.java ├── algorithm ├── BinaryNodeTest.java ├── HappyNumTest.java ├── LinkLoopTest.java ├── MergeTwoSortedListsTest.java ├── ReverseNodeTest.java ├── TwoStackQueueTest.java └── TwoSumTest.java └── proxy └── JDKProxyTest.java /.github/ISSUE_TEMPLATE: -------------------------------------------------------------------------------- 1 | **在提交issue之前请回答以下问题,谢谢!** 2 | 3 | > 建议首先查看是否已经有类似的 Issues (提交时可删除该提示) 4 | 5 | ### 你使用的是哪个版本 6 | 7 | ### 预期结果 8 | 9 | ### 实际结果 10 | 11 | ### 重现结果的步骤 12 | 13 | ### 其他相关信息 -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | 如果是文字类 PR,请按照 [中文排版指北](https://github.com/sparanoid/chinese-copywriting-guidelines) 进行编写(提交时可删除该提示)。 2 | 3 | **What kind of change does this PR introduce?** (check at least one) 4 | 5 | - [ ] Bugfix 6 | - [ ] Feature 7 | - [ ] Code style update 8 | - [ ] Refactor 9 | - [ ] Build-related changes 10 | - [ ] Other, please describe: 11 | 12 | 13 | **The description of the PR:** 14 | 15 | 16 | **Other information:** -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true 4 | script: mvn -DskipTests=true clean install 5 | 6 | 7 | branches: 8 | only: 9 | - master -------------------------------------------------------------------------------- /79884.log: -------------------------------------------------------------------------------- 1 | 2018-03-06 23:11:05 2 | Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.131-b11 mixed mode): 3 | 4 | "Attach Listener" #15 daemon prio=9 os_prio=31 tid=0x00007ffd7b08b800 nid=0x1407 waiting on condition [0x0000000000000000] 5 | java.lang.Thread.State: RUNNABLE 6 | 7 | "DestroyJavaVM" #14 prio=5 os_prio=31 tid=0x00007ffd7b001800 nid=0x1c03 waiting on condition [0x0000000000000000] 8 | java.lang.Thread.State: RUNNABLE 9 | 10 | "Blocked2" #13 prio=5 os_prio=31 tid=0x00007ffd7b08b000 nid=0x5503 waiting for monitor entry [0x00007000083d1000] 11 | java.lang.Thread.State: BLOCKED (on object monitor) 12 | at com.crossoverjie.concurrent.ThreadState$Blocked.run(ThreadState.java:59) 13 | - waiting to lock <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Blocked) 14 | at java.lang.Thread.run(Thread.java:748) 15 | 16 | "Blocked1" #12 prio=5 os_prio=31 tid=0x00007ffd7b08a000 nid=0x5303 waiting on condition [0x00007000082ce000] 17 | java.lang.Thread.State: TIMED_WAITING (sleeping) 18 | at java.lang.Thread.sleep(Native Method) 19 | at com.crossoverjie.concurrent.ThreadState$Blocked.run(ThreadState.java:59) 20 | - locked <0x000000079576cd60> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Blocked) 21 | at java.lang.Thread.run(Thread.java:748) 22 | 23 | "Waiting" #11 prio=5 os_prio=31 tid=0x00007ffd7b089800 nid=0x5103 in Object.wait() [0x00007000081cb000] 24 | java.lang.Thread.State: WAITING (on object monitor) 25 | at java.lang.Object.wait(Native Method) 26 | - waiting on <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Waiting) 27 | at java.lang.Object.wait(Object.java:502) 28 | at com.crossoverjie.concurrent.ThreadState$Waiting.run(ThreadState.java:42) 29 | - locked <0x0000000795768db0> (a java.lang.Class for com.crossoverjie.concurrent.ThreadState$Waiting) 30 | at java.lang.Thread.run(Thread.java:748) 31 | 32 | "TimeWaiting" #10 prio=5 os_prio=31 tid=0x00007ffd7b82c800 nid=0x4f03 waiting on condition [0x00007000080c8000] 33 | java.lang.Thread.State: TIMED_WAITING (sleeping) 34 | at java.lang.Thread.sleep(Native Method) 35 | at com.crossoverjie.concurrent.ThreadState$TimeWaiting.run(ThreadState.java:27) 36 | at java.lang.Thread.run(Thread.java:748) 37 | 38 | "Monitor Ctrl-Break" #9 daemon prio=5 os_prio=31 tid=0x00007ffd7a97e000 nid=0x4d03 runnable [0x0000700007fc5000] 39 | java.lang.Thread.State: RUNNABLE 40 | at java.net.PlainSocketImpl.socketAccept(Native Method) 41 | at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409) 42 | at java.net.ServerSocket.implAccept(ServerSocket.java:545) 43 | at java.net.ServerSocket.accept(ServerSocket.java:513) 44 | at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:79) 45 | at java.lang.Thread.run(Thread.java:748) 46 | 47 | "Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007ffd7a837800 nid=0x4903 runnable [0x0000000000000000] 48 | java.lang.Thread.State: RUNNABLE 49 | 50 | "C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007ffd7b030800 nid=0x4703 waiting on condition [0x0000000000000000] 51 | java.lang.Thread.State: RUNNABLE 52 | 53 | "C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007ffd7b029800 nid=0x4503 waiting on condition [0x0000000000000000] 54 | java.lang.Thread.State: RUNNABLE 55 | 56 | "C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007ffd7a813800 nid=0x4303 waiting on condition [0x0000000000000000] 57 | java.lang.Thread.State: RUNNABLE 58 | 59 | "Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007ffd7a839000 nid=0x4103 runnable [0x0000000000000000] 60 | java.lang.Thread.State: RUNNABLE 61 | 62 | "Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007ffd7b00b800 nid=0x3103 in Object.wait() [0x00007000078b0000] 63 | java.lang.Thread.State: WAITING (on object monitor) 64 | at java.lang.Object.wait(Native Method) 65 | - waiting on <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock) 66 | at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) 67 | - locked <0x0000000795588ec8> (a java.lang.ref.ReferenceQueue$Lock) 68 | at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) 69 | at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) 70 | 71 | "Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007ffd7a800800 nid=0x2f03 in Object.wait() [0x00007000077ad000] 72 | java.lang.Thread.State: WAITING (on object monitor) 73 | at java.lang.Object.wait(Native Method) 74 | - waiting on <0x0000000795586b68> (a java.lang.ref.Reference$Lock) 75 | at java.lang.Object.wait(Object.java:502) 76 | at java.lang.ref.Reference.tryHandlePending(Reference.java:191) 77 | - locked <0x0000000795586b68> (a java.lang.ref.Reference$Lock) 78 | at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) 79 | 80 | "VM Thread" os_prio=31 tid=0x00007ffd7a01a800 nid=0x2d03 runnable 81 | 82 | "GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007ffd7b005800 nid=0x2503 runnable 83 | 84 | "GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007ffd7b006000 nid=0x2703 runnable 85 | 86 | "GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007ffd7b006800 nid=0x2903 runnable 87 | 88 | "GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007ffd7b808000 nid=0x2b03 runnable 89 | 90 | "VM Periodic Task Thread" os_prio=31 tid=0x00007ffd7a03e000 nid=0x4b03 waiting on condition 91 | 92 | JNI global references: 21 93 | 94 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 crossoverJie 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MD/ArrayList.md: -------------------------------------------------------------------------------- 1 | # ArrayList/Vector 的底层分析 2 | 3 | ## ArrayList 4 | 5 | `ArrayList` 实现于 `List`、`RandomAccess` 接口。可以插入空数据,也支持随机访问。 6 | 7 | `ArrayList `相当于动态数据,其中最重要的两个属性分别是: 8 | `elementData` 数组,以及 `size` 大小。 9 | 在调用 `add()` 方法的时候: 10 | ```java 11 | public boolean add(E e) { 12 | ensureCapacityInternal(size + 1); // Increments modCount!! 13 | elementData[size++] = e; 14 | return true; 15 | } 16 | ``` 17 | 18 | - 首先进行扩容校验。 19 | - 将插入的值放到尾部,并将 size + 1 。 20 | 21 | 如果是调用 `add(index,e)` 在指定位置添加的话: 22 | ```java 23 | public void add(int index, E element) { 24 | rangeCheckForAdd(index); 25 | 26 | ensureCapacityInternal(size + 1); // Increments modCount!! 27 | //复制,向后移动 28 | System.arraycopy(elementData, index, elementData, index + 1, 29 | size - index); 30 | elementData[index] = element; 31 | size++; 32 | } 33 | ``` 34 | 35 | 36 | - 也是首先扩容校验。 37 | - 接着对数据进行复制,目的是把 index 位置空出来放本次插入的数据,并将后面的数据向后移动一个位置。 38 | 39 | 其实扩容最终调用的代码: 40 | ```java 41 | private void grow(int minCapacity) { 42 | // overflow-conscious code 43 | int oldCapacity = elementData.length; 44 | int newCapacity = oldCapacity + (oldCapacity >> 1); 45 | if (newCapacity - minCapacity < 0) 46 | newCapacity = minCapacity; 47 | if (newCapacity - MAX_ARRAY_SIZE > 0) 48 | newCapacity = hugeCapacity(minCapacity); 49 | // minCapacity is usually close to size, so this is a win: 50 | elementData = Arrays.copyOf(elementData, newCapacity); 51 | } 52 | ``` 53 | 54 | 也是一个数组复制的过程。 55 | 56 | 由此可见 `ArrayList` 的主要消耗是数组扩容以及在指定位置添加数据,在日常使用时最好是指定大小,尽量减少扩容。更要减少在指定位置插入数据的操作。 57 | 58 | ### 序列化 59 | 60 | 由于 ArrayList 是基于动态数组实现的,所以并不是所有的空间都被使用。因此使用了 `transient` 修饰,可以防止被自动序列化。 61 | 62 | ```java 63 | transient Object[] elementData; 64 | ``` 65 | 66 | 因此 ArrayList 自定义了序列化与反序列化: 67 | 68 | ```java 69 | private void writeObject(java.io.ObjectOutputStream s) 70 | throws java.io.IOException{ 71 | // Write out element count, and any hidden stuff 72 | int expectedModCount = modCount; 73 | s.defaultWriteObject(); 74 | 75 | // Write out size as capacity for behavioural compatibility with clone() 76 | s.writeInt(size); 77 | 78 | // Write out all elements in the proper order. 79 | //只序列化了被使用的数据 80 | for (int i=0; i