<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Jvm问题 on 随记</title><link>https://blog.liuyi2026.asia/zh/tags/jvm%E9%97%AE%E9%A2%98/</link><description>Recent content in Jvm问题 on 随记</description><generator>Hugo</generator><language>zh</language><lastBuildDate>Fri, 26 May 2023 09:29:06 +0000</lastBuildDate><atom:link href="https://blog.liuyi2026.asia/zh/tags/jvm%E9%97%AE%E9%A2%98/index.xml" rel="self" type="application/rss+xml"/><item><title>JDK代理和CGLIB代理</title><link>https://blog.liuyi2026.asia/zh/docs/problem/JVM/20230526/</link><pubDate>Fri, 26 May 2023 09:29:06 +0000</pubDate><guid>https://blog.liuyi2026.asia/zh/docs/problem/JVM/20230526/</guid><description>&lt;blockquote class='book-hint '>
&lt;p>完全转载自https://juejin.cn/post/7011357346018361375 ，以防丢失故作备份 。&lt;/p>&lt;/blockquote>&lt;h2 id="一什么是代理模式">一、什么是代理模式&lt;a class="anchor" href="#%e4%b8%80%e4%bb%80%e4%b9%88%e6%98%af%e4%bb%a3%e7%90%86%e6%a8%a1%e5%bc%8f">#&lt;/a>&lt;/h2>
&lt;p>代理模式（Proxy Pattern）给某一个对象提供一个代理，并由代理对象控制原对象的引用。代理对象在客户端和目标对象之间起到中介作用。&lt;/p>
&lt;p>代理模式是常用的结构型设计模式之一，当直接访问某些对象存在问题时可以通过一个代理对象来间接访问，为了保证客户端使用的透明性，所访问的真实对象与代理对象需要实现相同的接口。代理模式属于结构型设计模式，属于GOF23种设计模式之一。&lt;/p>
&lt;p>代理模式可以分为静态代理和动态代理两种类型，而动态代理中又分为JDK动态代理和CGLIB代理两种。
&lt;img src="img/ly-20241212141833243.png" alt="" />
&lt;strong>代理模式包含如下角色:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Subject (抽象主题角色)&lt;/strong> 抽象主题角色声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题 的地方都可以使用代理主题。客户端需要针对抽象主题角色进行编程。&lt;/li>
&lt;li>&lt;strong>Proxy (代理主题角色)&lt;/strong> 代理主题角色内部包含对真实主题的引用，从而可以在任何时候操作真实主题对象。 在代理主题角色中提供一个与真实主题角色相同的接口，以便在任何时候都可以替代真实 主体。代理主题角色还可以控制对真实主题的使用，负责在需要的时候创建和删除真实主 题对象,并对真实主题对象的使用加以约束。代理角色通常在客户端调用所引用的真实主 题操作之前或之后还需要执行其他操作，而不仅仅是单纯的调用真实主题对象中的操作。&lt;/li>
&lt;li>&lt;strong>RealSubject (真实主题 角色)&lt;/strong> 真实主题角色定义了代理角色所代表的真实对象，在真实主题角色中实现了真实的业 务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的方法。&lt;/li>
&lt;/ol>
&lt;h3 id="代理模式的优点">代理模式的优点&lt;a class="anchor" href="#%e4%bb%a3%e7%90%86%e6%a8%a1%e5%bc%8f%e7%9a%84%e4%bc%98%e7%82%b9">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>代理模式能将代理对象与真实被调用的目标对象分离。&lt;/li>
&lt;li>一定程度上降低了系统的耦合度，扩展性好。&lt;/li>
&lt;li>可以起到保护目标对象的作用。&lt;/li>
&lt;li>可以对目标对象的功能增强。&lt;/li>
&lt;/ul>
&lt;h3 id="代理模式的缺点">代理模式的缺点&lt;a class="anchor" href="#%e4%bb%a3%e7%90%86%e6%a8%a1%e5%bc%8f%e7%9a%84%e7%bc%ba%e7%82%b9">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>代理模式会造成系统设计中类的数量增加。&lt;/li>
&lt;li>在客户端和目标对象增加一个代理对象，会造成请求处理速度变慢。&lt;/li>
&lt;/ul>
&lt;h2 id="二jdk动态代理">二、JDK动态代理&lt;a class="anchor" href="#%e4%ba%8cjdk%e5%8a%a8%e6%80%81%e4%bb%a3%e7%90%86">#&lt;/a>&lt;/h2>
&lt;p>在java的动态代理机制中，有两个重要的类或接口，一个是 &lt;code>InvocationHandler&lt;/code>(Interface)、另一个则是 &lt;code>Proxy&lt;/code>(Class)，这一个类和接口是实现我们动态代理所必须用到的。&lt;/p>
&lt;h3 id="invocationhandler">InvocationHandler&lt;a class="anchor" href="#invocationhandler">#&lt;/a>&lt;/h3>
&lt;p>每一个动态代理类都必须要实现InvocationHandler这个接口，并且每个代理类的实例都关联了一个handler，当我们通过代理对象调用一个方法的时候，这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。&lt;/p>
&lt;p>InvocationHandler这个接口的唯一一个方法 invoke 方法：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>复制代码Object &lt;span style="color:#a6e22e">invoke&lt;/span>(Object proxy, Method method, Object&lt;span style="color:#f92672">[]&lt;/span> args) &lt;span style="color:#66d9ef">throws&lt;/span> Throwable&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这个方法一共接受三个参数，那么这三个参数分别代表如下：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>proxy&lt;/strong>:指代JDK动态生成的最终代理对象&lt;/li>
&lt;li>&lt;strong>method&lt;/strong>:指代的是我们所要调用真实对象的某个方法的Method对象&lt;/li>
&lt;li>&lt;strong>args&lt;/strong>:指代的是调用真实对象某个方法时接受的参数&lt;/li>
&lt;/ul>
&lt;h3 id="proxy">Proxy&lt;a class="anchor" href="#proxy">#&lt;/a>&lt;/h3>
&lt;p>Proxy这个类的作用就是用来动态创建一个代理对象的类，它提供了许多的方法，但是我们用的最多的就是newProxyInstance 这个方法：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-java" data-lang="java">&lt;span style="display:flex;">&lt;span>java
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>复制代码public &lt;span style="color:#66d9ef">static&lt;/span> Object &lt;span style="color:#a6e22e">newProxyInstance&lt;/span>(ClassLoader loader, Class&lt;span style="color:#f92672">&amp;lt;?&amp;gt;[]&lt;/span> interfaces, InvocationHandler handler) &lt;span style="color:#66d9ef">throws&lt;/span> IllegalArgumentException&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>这个方法的作用就是得到一个动态的代理对象，其接收三个参数，我们来看看这三个参数所代表的含义：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>loader&lt;/strong>：ClassLoader对象，定义了由哪个ClassLoader来对生成的代理对象进行加载，即代理类的类加载器。&lt;/li>
&lt;li>&lt;strong>interfaces&lt;/strong>：Interface对象的数组，表示的是我将要给我需要代理的对象提供一组什么接口，如果我提供了一组接口给它，那么这个代理对象就宣称实现了该接口(多态)，这样我就能调用这组接口中的方法了。&lt;/li>
&lt;li>&lt;strong>Handler&lt;/strong>：InvocationHandler对象，表示的是当我这个动态代理对象在调用方法的时候，会关联到哪一个InvocationHandler对象上。&lt;/li>
&lt;/ul>
&lt;p>所以我们所说的DynamicProxy（动态代理类）是这样一种class：它是在运行时生成的class，在生成它时你必须提供一组interface给它，然后该class就宣称它实现了这些 interface。这个DynamicProxy其实就是一个Proxy，它不会做实质性的工作，在生成它的实例时你必须提供一个handler，由它接管实际的工作。&lt;/p></description></item><item><title>linux中调试open jdk</title><link>https://blog.liuyi2026.asia/zh/docs/problem/JVM/2023052302/</link><pubDate>Tue, 23 May 2023 14:29:06 +0000</pubDate><guid>https://blog.liuyi2026.asia/zh/docs/problem/JVM/2023052302/</guid><description>&lt;blockquote class='book-hint '>
&lt;p>完全转载自https://lin1997.github.io/2020/07/19/debug-openjdk-on-ubuntu.html ，以防丢失故作备份，目前还没看懂。&lt;/p>&lt;/blockquote>&lt;h1 id="在ubuntu中编译和调试openjdk">在Ubuntu中编译和调试OpenJDK&lt;a class="anchor" href="#%e5%9c%a8ubuntu%e4%b8%ad%e7%bc%96%e8%af%91%e5%92%8c%e8%b0%83%e8%af%95openjdk">#&lt;/a>&lt;/h1>
&lt;ul>
&lt;li>
&lt;p>
&lt;a target="_blank" href="https://lin1997.github.io/archive.html?tag=OpenJDK">OpenJDK&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>
&lt;a target="_blank" href="https://lin1997.github.io/archive.html?tag=Ubuntu">Ubuntu&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>
&lt;a target="_blank" href="https://lin1997.github.io/archive.html?tag=CLion">CLion&lt;/a>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>2020年 07月19日&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="构建编译环境">构建编译环境&lt;a class="anchor" href="#%e6%9e%84%e5%bb%ba%e7%bc%96%e8%af%91%e7%8e%af%e5%a2%83">#&lt;/a>&lt;/h2>
&lt;p>安装GCC编译器：&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo apt install build-essential&lt;/code>&lt;/pre>&lt;p>安装OpenJDK依赖库：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>工具&lt;/th>
 &lt;th>库名称&lt;/th>
 &lt;th>安装命令&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>FreeType&lt;/td>
 &lt;td>The FreeType Project&lt;/td>
 &lt;td>&lt;code>sudo apt install libfreetype6-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CUPS&lt;/td>
 &lt;td>Common UNIX Printing System&lt;/td>
 &lt;td>&lt;code>sudo apt install libcups2-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>X11&lt;/td>
 &lt;td>X Window System&lt;/td>
 &lt;td>&lt;code>sudo apt install libx11-dev libxext-dev libxrender-dev libxrandr-dev libxtst-dev libxt-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>ALSA&lt;/td>
 &lt;td>Advanced Linux Sound Architecture&lt;/td>
 &lt;td>&lt;code>sudo apt install libasound2-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>libffi&lt;/td>
 &lt;td>Portable Foreign Function Interface&lt;/td>
 &lt;td>&lt;code>sudo apt install libffi-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Autoconf&lt;/td>
 &lt;td>Extensible Package of M4 Macros&lt;/td>
 &lt;td>&lt;code>sudo apt install autoconf&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>zip/unzip&lt;/td>
 &lt;td>unzip&lt;/td>
 &lt;td>&lt;code>sudo apt install zip unzip&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>fontconfig&lt;/td>
 &lt;td>fontconfig&lt;/td>
 &lt;td>&lt;code>sudo apt install libfontconfig1-dev&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>假设要编译大版本号为N的JDK，我们还要安装一个大版本号&lt;strong>至少为N-1&lt;/strong>的、已经编译好的JDK作为“Bootstrap JDK”：&lt;/p></description></item></channel></rss>