<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>ErCargo's Coffee Time</title>
    <description>Action Conquers Fear, Impetuous, Indolence and so on. (行动能够克服一切恐惧，浮躁，懒惰)</description>
    <link>https://github.com/ErCargo/</link>
    <atom:link href="https://github.com/ErCargo/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 11 May 2020 08:49:33 +0000</pubDate>
    <lastBuildDate>Mon, 11 May 2020 08:49:33 +0000</lastBuildDate>
    <generator>Jekyll v3.8.5</generator>
    
      <item>
        <title>微服务学习笔记</title>
        <description>&lt;ul&gt;
  &lt;li&gt;微服务的拆分&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;微服务的拆分方法&quot;&gt;微服务的拆分方法&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Domain Driven Design&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;《领域驱动设计 - 软件核心复杂性应对之道》&lt;/p&gt;

&lt;p&gt;《实现-领域驱动设计》&lt;/p&gt;

&lt;p&gt;《领域驱动设计 - 精简版》&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;面向对象拆分&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By Name&lt;/p&gt;

&lt;p&gt;By Verb&lt;/p&gt;

&lt;p&gt;拆分的维度&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;按照职责划分&lt;/li&gt;
  &lt;li&gt;按照通用性划分（中台）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;微服务的粒度&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;满足业务需求&lt;/li&gt;
  &lt;li&gt;增量迭代&lt;/li&gt;
  &lt;li&gt;持续进化&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;服务注册与服务发现&quot;&gt;服务注册与服务发现&lt;/h2&gt;

&lt;p&gt;服务发现：服务消费者总能找到服务提供者的机制&lt;/p&gt;

&lt;p&gt;如何实现服务发现&lt;/p&gt;

&lt;p&gt;原理： 注册中心&lt;/p&gt;

</description>
        <pubDate>Wed, 10 Apr 2019 22:10:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/04/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/04/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid>
        
        
      </item>
    
      <item>
        <title>设计模式</title>
        <description>
</description>
        <pubDate>Mon, 08 Apr 2019 18:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/04/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/04/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</guid>
        
        
      </item>
    
      <item>
        <title>算法！算法！</title>
        <description>
</description>
        <pubDate>Fri, 05 Apr 2019 15:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/04/%E7%AE%97%E6%B3%95!%E7%AE%97%E6%B3%95!/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/04/%E7%AE%97%E6%B3%95!%E7%AE%97%E6%B3%95!/</guid>
        
        
      </item>
    
      <item>
        <title>Spring 技术内幕学习笔记</title>
        <description>
</description>
        <pubDate>Mon, 01 Apr 2019 13:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/04/Spring%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/04/Spring%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid>
        
        
      </item>
    
      <item>
        <title>Redis 知识点梳理</title>
        <description>
</description>
        <pubDate>Fri, 22 Mar 2019 13:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/Redis-%E7%9F%A5%E8%AF%86%E7%82%B9%E6%A2%B3%E7%90%86/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/Redis-%E7%9F%A5%E8%AF%86%E7%82%B9%E6%A2%B3%E7%90%86/</guid>
        
        
      </item>
    
      <item>
        <title>Spring Cloud 组件分析</title>
        <description>&lt;h2 id=&quot;spring-cloud&quot;&gt;Spring Cloud&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;快速开发分布式应用的工具集&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;spring-cloud-主要功能&quot;&gt;Spring Cloud 主要功能&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;功能&lt;/th&gt;
      &lt;th&gt;功能详情&lt;/th&gt;
      &lt;th&gt;组件&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Distributed/versioned configuration&lt;/td&gt;
      &lt;td&gt;分布式/版本化配置管理&lt;/td&gt;
      &lt;td&gt;Spring Cloud Config; Consul; Zookeeper; Nacos&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Service registration and discovery&lt;/td&gt;
      &lt;td&gt;服务注册与服务发现&lt;/td&gt;
      &lt;td&gt;Eureka; Consul; Zookeeper; Nacos&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Routing&lt;/td&gt;
      &lt;td&gt;路由&lt;/td&gt;
      &lt;td&gt;Zuul; Spring Cloud Gateway&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Service-to-Service calls&lt;/td&gt;
      &lt;td&gt;端到端的调用&lt;/td&gt;
      &lt;td&gt;RestTemplate; Feign&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Load balancing&lt;/td&gt;
      &lt;td&gt;负载均衡&lt;/td&gt;
      &lt;td&gt;Ribbon&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Circuit Breakers&lt;/td&gt;
      &lt;td&gt;断路器&lt;/td&gt;
      &lt;td&gt;Hystrix; Resilience4J; Sentinel&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Global locks&lt;/td&gt;
      &lt;td&gt;全局锁&lt;/td&gt;
      &lt;td&gt;Spring Cloud Clutser(Spring Integration)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Leadership election and cluster state&lt;/td&gt;
      &lt;td&gt;选举与集群状态管理&lt;/td&gt;
      &lt;td&gt;Spring Cloud Clutser(Spring Integration)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Distributed messaging&lt;/td&gt;
      &lt;td&gt;分布式消息&lt;/td&gt;
      &lt;td&gt;Spring Cloud Stream + Kafka/RabbitMQ/RocketMQ&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;spring-cloud-常用组件&quot;&gt;Spring Cloud 常用组件&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/spring-cloud-zj.jpg&quot; alt=&quot;zj&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;spring-cloud-版本与兼容性&quot;&gt;Spring cloud 版本与兼容性&lt;/h3&gt;

&lt;p&gt;Spring Cloud 版本命名: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://spring.io/projects/spring-cloud#learn&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;版本顺序:&lt;/p&gt;

&lt;p&gt;Angel Brixton Camden  Dalston Edgware Finchley Greenwich Hoxton&lt;/p&gt;

&lt;p&gt;指定版本的发布流程：&lt;/p&gt;

&lt;p&gt;SNAPSHOT -&amp;gt; Mx -&amp;gt; RELEASE -&amp;gt; SRx&lt;/p&gt;

&lt;p&gt;Spring Cloud 生命周期&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;版本发布规划: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://github.com/spring-cloud/spring-cloud-release/milestones&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;版本发布记录: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://github.com/spring-cloud/spring-cloud-release/releases&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;版本终止声明:  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://spring.io/projects/spring-cloud#overview&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Spring cloud 和 Spring Boot 的版本兼容性: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://spring.io/projects/spring-cloud&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/version.jpg&quot; alt=&quot;version&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;服务注册与服务发现&quot;&gt;服务注册与服务发现&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;什么是服务发现？&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;让服务消费者总能找服务提供者的一种机制&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;服务发现组件(注册中心) consul&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 20 Mar 2019 23:10:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/Spring-Cloud%E7%BB%84%E4%BB%B6%E5%88%86%E6%9E%90/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/Spring-Cloud%E7%BB%84%E4%BB%B6%E5%88%86%E6%9E%90/</guid>
        
        
      </item>
    
      <item>
        <title>多线程之 ThreadLocal</title>
        <description>&lt;ul&gt;
  &lt;li&gt;Pre talk&lt;/li&gt;
  &lt;li&gt;ThreadLocal 是什么？解决了什么问题？&lt;/li&gt;
  &lt;li&gt;ThreadLocal 源码分析及实现原理&lt;/li&gt;
  &lt;li&gt;ThreadLocal 内存泄漏问题&lt;/li&gt;
  &lt;li&gt;InheritableThreadLocal 的实现原理&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
&lt;h2 id=&quot;pre-talk&quot;&gt;Pre talk&lt;/h2&gt;

&lt;h3 id=&quot;线程封闭技术&quot;&gt;线程封闭技术&lt;/h3&gt;
&lt;p&gt;访问共享可变数据时，通常需要使用同步，同步会产生性能问题，如何避免使用同步的方式来保证线程安全问题 – 不共享数据， 如何保证数据不共享呢？
如果仅仅是在单线程内访问数据，就不会存在数据共享的问题，也就不需要数据同步。 (线程封闭: Thread Confinement， 是实现线程安全最简单的方式之一)&lt;/p&gt;

&lt;p&gt;当某个对象被封闭在一个线程中时， 这种用法将自动实现线程安全性，即使被封闭的对象本身不是线程安全的。&lt;/p&gt;

&lt;p&gt;线程封闭常用的场景：JDBC 的 Connection 对象（非线程安全的连接池是没有意义的）&lt;/p&gt;

&lt;p&gt;几种线程封闭技术&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Ad-hoc 线程封闭： 由程序来承担维护线程封闭性的职责（脆弱的）&lt;/li&gt;
  &lt;li&gt;栈封闭: 通过局部变量才能访问对象，局部变量的固有属性就是封闭在执行线程中（执行线程的栈中，因为变量是在栈中，栈是线程独立的）&lt;/li&gt;
  &lt;li&gt;ThreadLocal: 是维持线程封闭性的规范的方法。ThreadLocal 能使线程中的某个值与保存值的对象关联起来。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;threadlocal-是什么解决了什么问题&quot;&gt;ThreadLocal 是什么、解决了什么问题？&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/ThreadLocal.jpg&quot; alt=&quot;jdk1.8 ThreadLocal&quot; /&gt;&lt;/p&gt;

&lt;p&gt;粗略的解释：ThreadLocal 类提供了线程本地的实例变量。这些变量与普通变量的区别在于：每个使用该变量的线程都会初始化一个独立的副本， ThreadLocal 修饰的实例，是一个典型的和线程相关联的私有的静态变量… （能力有限翻译不出来了）&lt;/p&gt;

&lt;p&gt;ThreadLocal 对象通常用于防止对「可变的单实例变量」或「全局变量」进行共享，如 全局的数据库连接（Connection）。&lt;/p&gt;

&lt;p&gt;ThreadLocal 通常称为：线程本地变量/线程本地存储。ThreadLocal 提供了 get 和 set 方法，为每一个使用该变量的线程存有一份独立的副本。（ get 总是返回的当前执行线程在调用 set 时设置的最新值 ）&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一句话总结&lt;/strong&gt;: ThreadLocal 为每个线程提供局部变量， 每个线程都可以通过 set() get() 对这个局部变量进行操作，但不会和其他线程的局部变量产生冲突， 进而实现线程的数据隔离，保证线程安全。&lt;/p&gt;

&lt;p&gt;另外一定要注意:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;ThreadLocal 不是用来解决共享对象的多线程访问问题， 通过 ThreadLocal.set() 到线程中的对象是该线程自己使用的对应，其他线程是不需要访问的，也访问不到；（各个线程中访问的是不同的对象）&lt;/li&gt;
  &lt;li&gt;ThreadLocal 使得各线程能够保持各自独立的对象， 并不是通过 ThreadLocal.set() 来实现的， 而是通过 每个线程中的 new 对象的操作来创建的对象，每个线程创建一个。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最常见的 ThreadLocal 使用场景是用来解决「数据库连接」、「Session 管理」等问题。&lt;/p&gt;

&lt;h2 id=&quot;threadlocal-源码分析及实现原理&quot;&gt;ThreadLocal 源码分析及实现原理&lt;/h2&gt;

&lt;p&gt;set()&lt;/p&gt;

</description>
        <pubDate>Wed, 06 Mar 2019 16:39:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B9%8BThreadLocal/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/%E5%A4%9A%E7%BA%BF%E7%A8%8B%E4%B9%8BThreadLocal/</guid>
        
        
      </item>
    
      <item>
        <title>多线程</title>
        <description>&lt;h2 id=&quot;进程和线程的区别&quot;&gt;进程和线程的区别&lt;/h2&gt;

&lt;p&gt;抽象答案：进程是资源分配的最小单位， 线程是 CPU 调度的最小单位&lt;/p&gt;

&lt;p&gt;如何组织语言能够描述清楚呢？&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;一个进程可以包含多个线程&lt;/li&gt;
  &lt;li&gt;进程间难以数据共享， 但是同一进程下的不同线程是可以进行数据共享的；&lt;/li&gt;
  &lt;li&gt;进程比线程消耗更多的 CPU 资源；&lt;/li&gt;
  &lt;li&gt;进程与进程之间的运行不会相互影响， 但是线程之间会相互影响；&lt;/li&gt;
  &lt;li&gt;一个线程使用共享内存时，其他线程必须等待他结束，才能使用这块区域（互斥锁）&lt;/li&gt;
  &lt;li&gt;进程使用的内存地址可以限定使用量（信号量）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;……&lt;/p&gt;
</description>
        <pubDate>Tue, 05 Mar 2019 20:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/%E5%A4%9A%E7%BA%BF%E7%A8%8B/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/%E5%A4%9A%E7%BA%BF%E7%A8%8B/</guid>
        
        
      </item>
    
      <item>
        <title>聊聊 GC</title>
        <description>&lt;p&gt;– Java 垃圾回收机制
– 常见的垃圾收集器
– Java 中的各种引用&lt;/p&gt;

&lt;h2 id=&quot;java-垃圾回收机制&quot;&gt;Java 垃圾回收机制&lt;/h2&gt;

&lt;h3 id=&quot;对象什么情况下被看作是垃圾&quot;&gt;对象什么情况下被看作是垃圾？&lt;/h3&gt;

&lt;p&gt;对象不被任何其他对象引用时，就可以被认为是垃圾对象，就可以被内存回收&lt;/p&gt;

&lt;h3 id=&quot;如何判断对象是否为垃圾&quot;&gt;如何判断对象是否为垃圾？&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;引用计数算法
    &lt;ul&gt;
      &lt;li&gt;判断对象的引用数量来决定是否可以被回收，引用计数器为 0 时就可以被回收;&lt;/li&gt;
      &lt;li&gt;但是不可避免循环引用的问题;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;可达性分析算法(主流的 JVM 使用的算法)&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;判断对象的引用链是否可达， 来决定队形是否可被回收；&lt;/li&gt;
      &lt;li&gt;引用离散数学中的图论，GC Root；&lt;/li&gt;
      &lt;li&gt;可以被作为 GC root 的对象有：
        &lt;ul&gt;
          &lt;li&gt;虚拟机栈中引用的对象&lt;/li&gt;
          &lt;li&gt;方法区中常量引用对象&lt;/li&gt;
          &lt;li&gt;方法区中类静态属性引用对象&lt;/li&gt;
          &lt;li&gt;本地方法栈中引用的对象&lt;/li&gt;
          &lt;li&gt;活跃线程的对象&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;垃圾回收算法&quot;&gt;垃圾回收算法&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;标记 - 清除算法&lt;/li&gt;
  &lt;li&gt;复制算法（对象面、空闲面），适用于对象存活率低的场景（年轻代）&lt;/li&gt;
  &lt;li&gt;标记 - 整理算法， 适用于对象存活率较高的场景（老年代）&lt;/li&gt;
  &lt;li&gt;分代回收算法&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;分代回收算法&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/GC.jpg&quot; alt=&quot;GC&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;年轻代（Young Generation） Eden 区 、 2 个 Survivor 区&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;老年代（Old Generation&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;分代回收的 GC 分类&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Minor GC 发生在年轻代中（复制算法）&lt;/li&gt;
  &lt;li&gt;Full GC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;触发 Full GC 的条件&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;老年大空间不足， 不够放下一个大对象；（不要创建太大的对象）&lt;/li&gt;
  &lt;li&gt;永久代（jdk1.8-）为什么用元空间替代永久代， 也是为了降低 Full GC 的频率&lt;/li&gt;
  &lt;li&gt;CMS  GC 时 出现 promotion failed, concurrent mode filure&lt;/li&gt;
  &lt;li&gt;System.gc()&lt;/li&gt;
  &lt;li&gt;RMI RPC  /管理 JDK 应用， 每 1 小时执行一个 Full GC&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;常用的调优参数
|      参数          | 含义                                            |
| ——————– | —————————————————|
| -XX:SurvivorRatio    |  Eden 和 其中一个Survivor 的比值 默认 8:1             |
| -XX:NewRatio         |  老年代和年轻代的比例（e.g: 如果值为 2 表示 2:1）          |
| -Xms -Xms            | 新生代和老年代的总内存大小                                |
| -XX:MaxTenuringThreshold       |   对象从年轻代晋升到老年代经过 GC 次数的最大阈值  |&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stop-the-world&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JVM 由于要执行 GC 而停止了应用程序的执行， 会在任何一种 GC 算法中发生， 当Stop-the-world 发生时，除了 GC 所使用的线程；
经常说的 GC 优化就是通过减少 Stop-the-world 发生的时间来提高程序性能&lt;/p&gt;

&lt;h2 id=&quot;常见的垃圾收集器&quot;&gt;常见的垃圾收集器&lt;/h2&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/gc_cat.jpg&quot; alt=&quot;gc_cat&quot; /&gt;&lt;/p&gt;

&lt;p&gt;CMS 收集器&lt;/p&gt;

&lt;p&gt;G1 收集器 Garbage First（复制 + 标记-整理算法）既用于年轻代， 又用于老年代&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;并行和并发（多个 CPU 缩短 stop-the-world 的时间， 与用户线程并发执行）&lt;/li&gt;
  &lt;li&gt;分代收集&lt;/li&gt;
  &lt;li&gt;空间整合（标记-整理算法）&lt;/li&gt;
  &lt;li&gt;可预测的停顿&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Epsillon GC 
ZGC&lt;/p&gt;

&lt;h2 id=&quot;java-中的各种引用&quot;&gt;Java 中的各种引用&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;强引用（strong  reference）&lt;/p&gt;

    &lt;p&gt;Object obj = new Object()&lt;/p&gt;

    &lt;p&gt;不会回收具有强引用的对象（OOM），只能通过将对象设置为 null 的方式来弱化引用， 使其被回收&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;软引用(soft reference)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;SoftReference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;soft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SoftReference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 软引用&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;有用，但非必须， 当内存空间不足时， GC 会回收该引用的对象内存,， 但 GC 线程优先级较低&lt;/p&gt;

&lt;p&gt;可以用来实现高速缓存&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;弱引用（week reference）&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;   &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
   &lt;span class=&quot;nc&quot;&gt;WeakReference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;soft&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WeakReference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 软引用&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;非必须的，类似软引用, 比软引用更弱
  无论内存是否够用， GC 都会回收弱引用对象&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;虚引用（Phantom reference）&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;c1&quot;&gt;// 虚引用&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;aaa&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;ReferenceQueue&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ReferenceQueue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;PhantomReference&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ref&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PhantomReference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;不会决定对象的生命周期&lt;/p&gt;

&lt;p&gt;任何时候都会被 GC 回收&lt;/p&gt;

&lt;p&gt;主要用来跟踪对象被 GC 回收的活动， 起哨兵的作用， 必须和 ReferenceQueue 联合使用&lt;/p&gt;

&lt;hr /&gt;

</description>
        <pubDate>Sat, 02 Mar 2019 13:45:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/%E8%81%8A%E8%81%8A-GC/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/%E8%81%8A%E8%81%8A-GC/</guid>
        
        
      </item>
    
      <item>
        <title>Java 内存模型</title>
        <description>&lt;ul&gt;
  &lt;li&gt;内存简介&lt;/li&gt;
  &lt;li&gt;JVM 架构图&lt;/li&gt;
  &lt;li&gt;Java 内存模型&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;内存&quot;&gt;内存&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;计算机程序都是在内存中运行的(包括虚拟内存)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;在程序运行过程中， 需要不断的将内存的「逻辑地址」和「物理地址」进行映射，找到相关的【指令】以及【数据】去执行
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;逻辑地址  -&amp;gt;  分段管理机制 -&amp;gt; 线性地址 -&amp;gt;  分页管理机制 -&amp;gt;  物理地址&lt;/p&gt;

&lt;p&gt;Java 程序实际上是一个操作系统进程， 与其他进程一样面临内存限制，即受限于操作系统架构提供的「可寻址地址空间」 （可寻址地址空间由处理器的位数决定（32位/64位））&lt;/p&gt;

&lt;p&gt;地址空间划分为：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;内核空间（操作系统程序， c 运行时的空间 ， 连接计算机硬件，调度程序，提供联网和虚拟内存等服务的逻辑和基于 C 的进程）&lt;/li&gt;
  &lt;li&gt;用户空间（java 进程实际运行时使用的内存空间）&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;jvm-架构图&quot;&gt;JVM 架构图&lt;/h2&gt;
&lt;p&gt;ref: &lt;a href=&quot;/2019/02/Java虚拟机学习笔记&quot;&gt;《Java虚拟机学习笔记》&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;其中 Runtime Data Area 就是 Java 的内存模型&lt;/p&gt;

&lt;h2 id=&quot;java-内存模型&quot;&gt;Java 内存模型&lt;/h2&gt;

&lt;p&gt;Java 程序运行在虚拟机之上，运行时需要内存空间，虚拟机在执行 Java 程序的过程中会把「他管理的内存」划分不同的数据区域.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;「C 编译器」会将内存区域划分为：数据段（包括「堆」「栈」「静态数据区」）和代码段&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Q: JDK 8 是如何划分内存空间的？&lt;/p&gt;

&lt;h3 id=&quot;从线程的角度讨论&quot;&gt;从线程的角度讨论&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;线程私有的区域&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;程序计数器&lt;/li&gt;
  &lt;li&gt;虚拟机栈(Stack)&lt;/li&gt;
  &lt;li&gt;本地方法栈(带有 Native 关键字的方法使用的内存空间)&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Java 方法执行的内存模型， 每个方法被执行时都会创建一个栈帧（栈帧是方法运行期间的基础数据结构）存放在虚拟机栈中；
「栈帧」用于存储局部变量表，操作数栈， 动态连接，返回地址等
- 当方法被调用时，jvm 会开辟一块空间(会创建一个栈帧)；
- 当方法调用结束时，栈帧就会被销毁；（这也是为什么栈的内存不需要通过 GC 回收， 而是自动释放）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/stack_frame.jpg&quot; alt=&quot;栈帧&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;局部变量表：包括了方法执行过程中的所有变量，this 引用，所有方法参数，其他局部变量&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;操作数栈： 在执行字节码指令时被用到，类似于原生 CPU 寄存器，大部分 JVM 字节码把时间花费在 操作数栈上，包括入栈，出栈，复制，交换，产生消费变量等&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Q: 递归为什么会引起 java.lang.StackOverflow 异常？&lt;/p&gt;
&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;com&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ercargo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;cm&quot;&gt;/**
 * @author ercargo  on 2020/4/5
 * @DESCRIBE
 * 0，1，1，2，3，5，8，13...
 * F(0) = 0
 * F(1) = 1
 * F(n) = F(n-1) + F(n-2)
 * e.g：
 * F(2) = F(1) + F(0) = 1
 * F(3) = F(2) + F(1) = 2
 */&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Fibonacci&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;

        &lt;span class=&quot;nc&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000000&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;每【执行】一次方法时， 就会创建一个栈帧， 并将栈帧压入虚拟机栈中，方法执行完成时， 会将栈帧出栈
递归过深，方法调用次数过多， 创建的栈帧数就越多， 当栈帧数会超出整个虚拟机栈的深度时， 就会报错：&lt;/p&gt;

&lt;div class=&quot;language-java highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thread&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;StackOverflowError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;解决方法: 限制递归深度/循环替代&lt;/p&gt;

&lt;p&gt;另外：虚拟机栈过多也会引发 java.lang.OutOfMemoryError 异常&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;线程共享的区域&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;元空间 MetaSpace(类加载信息)&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;在 jdk8 以后开始把类的元数据放在本地堆内存中，称为 MetaSpace(在 jdk7 以前是属于永久代的)，元空间和永久代都是用来存储 Class 信息，包括 Class 对象的 method ,field 等
元空间和永久代都是方法区（Method Area）的实现，方法区只是一种 JVM 的规范；
- 在 Java 7 之后原先位于【方法区（Method Area）】里的「字符串常量池」被移动到 「Java 堆（Heap）」中， 
- 并且使用元空间替代了永久代（java.lang.OutOfMemoryError: PermGen space 不复存在）
上面这部分内容还是要参照 JVM 架构图来理解，主要是 Runtime Data Area 包含的部分 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;Java 堆(数组和类对象)常量池（字面量和符号引用）&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;对象实例的分配区域， Java 堆可以处于物理上不连续的内存空间中， 只要逻辑上是连续的就可以， 可扩展的
-Xmx  
-Xms
-Xss

GC 管理的主要区域（分代回收算法）
    新生代                              老年代
Eden 「from survivor」「to Survivor」  tenured
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;从存储的角度讨论&quot;&gt;从存储的角度讨论&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;JVM 3 大性能调优参数&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
  &lt;li&gt;Xss    规定了每个线程虚拟机栈的大小 （256k）该配置影响进程中并发线程数的大小；&lt;/li&gt;
  &lt;li&gt;Xms    堆的初始值               （该进程刚创建出来时 java 堆的大小，一旦对象容量超过了 java 堆的初始容量， java 堆将会自动扩容， 扩容至 -Xmx 设置的大小）&lt;/li&gt;
  &lt;li&gt;Xmx    堆能扩展到的最大值        （一般 -Xms 和 -Xmx 的值相等， 堆的扩容会发生内存抖动，影响程序运行时的稳定性）&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Java 内存模型中「堆」和「栈」的区别:&lt;/p&gt;

    &lt;p&gt;程序运行时的内存分配策略:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;静态存储: 在编译时确定每个数据目标在运行时的存储空间需求；(不允许可变数据存储，递归等)&lt;/li&gt;
      &lt;li&gt;栈式存储: 数据去需求在编译时未知，运行时模块入口前确定；&lt;/li&gt;
      &lt;li&gt;堆式存储: 编译/运行时都不能确定， 动态分配&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;区别 1： 栈存放对象的地址
        堆存放对象实例
区别 2： 栈自动释放内存
        堆需要 GC 
区别 3： 栈比堆小&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/memory.jpg&quot; alt=&quot;内存&quot; /&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;元空间，堆，线程独占部分的联系&lt;/li&gt;
  &lt;li&gt;intern() 方法&lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Fri, 01 Mar 2019 23:13:00 +0000</pubDate>
        <link>https://github.com/ErCargo/2019/03/Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</link>
        <guid isPermaLink="true">https://github.com/ErCargo/2019/03/Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/</guid>
        
        
      </item>
    
  </channel>
</rss>
