Java 程式優化 (讀書筆記)

来源:http://www.cnblogs.com/yd137730268/archive/2016/12/21/6206891.html
-Advertisement-
Play Games

--From : JAVA程式性能優化 (葛一鳴,清華大學出版社,2012/10第一版) 1. java性能調優概述 1.1 性能概述 程式性能: 執行速度,記憶體分配,啟動時間, 負載承受能力。 性能指標: 執行時間,CPU時間,記憶體分配,磁碟吞吐量,網路吞吐量,響應時間。 優化策略: 木桶原理,優 ...


--From : JAVA程式性能優化 (葛一鳴,清華大學出版社,2012/10第一版)

 

1. java性能調優概述

    1.1 性能概述 

        程式性能: 執行速度,記憶體分配,啟動時間, 負載承受能力。

        性能指標: 執行時間,CPU時間,記憶體分配,磁碟吞吐量,網路吞吐量,響應時間。 

        優化策略: 木桶原理,優化性能瓶頸。

    1.2 性能調優的層次

        設計調優,

        代碼調優,

        JVM調優,

        資料庫調優,

        操作系統調優。

        

2. 設計優化

    2.1 善用設計模式 

        單例模式: 對於巨大對象,節省創建對象的時間空間;

        代理模式: 可用於延遲載入,提升系統啟動速度;

        享元模式: 對象和組件復用,節省創建對象的開銷;

        裝飾者模式: 分離組件,提高可維護性增加模塊復用性;

        觀察者模式: 避免新開線程迴圈等待;

    2.2 常用組件優化

        緩衝(漏斗設計), 

        緩存(空間換時間), 

        對象復用“池”, 

        並行代替串列,

        負載均衡(Terracotta), 

        時間換空間,

        空間換時間。

        

3. Java程式優化

    3.1 字元串 

        不變性, 針對常量池優化

        subString 空間換取時間

        split 正則分割

        StringTokenizer 字元串分割

        靈活使用charAt 和 indexOf

        StringBuffer(線程安全) 和 StringBuilder : 初始化時設置最大容量

    3.2 核心數據結構

        List : ArrayList 和  LinkedList

        Map  : Hashtable(線程安全), HashMap, LinkedHashMap, TreeMap(可排序)

        Set  : hashSet, linkedHashSet, TreeSet

        集合訪問優化 :

            分離迴圈中被重覆調用的代碼 ( i<collection.size() -> i<collectionSize )

            省略相同的操作 (迴圈內部的聲明)

            減少方法調用 (優先直接訪問內部變數)

        RandomAccess (隨即訪問): ArrayList Vector

    3.3 使用NIO提升性能

        NIO的Buffer 和 Channel 配合使用

        Buffer的原理和相關操作

        Buffer記憶體緩存和堆上記憶體區別

    3.4 引用類型

        強引用 : 可以直接訪問,不會被GC回收,可能導致記憶體泄露(互相引用)

        軟引用 : SoftReference<T> 記憶體緊張,會被GC回收

        弱引用 : WeakReference<T> GC發現立即回收

        虛引用 : PhantomReference<T> 始終返回null

        WeakHashMap : 弱引用的 HashMap

    3.5 改善性能

        慎用異常,try catch浪費性能 (62ms/110ms)

        使用局部變數,棧的訪問比堆快 (78ms/266ms)

        位運算代替乘除法            (31ms/219ms)

        一維數組代替二維數組        (235ms/344ms)

        提取公共表達式

        降低迴圈次數 如數組賦值 i++ -> i+=3 (31ms/94ms)

        布爾運算代替位運算 (邏輯運算中布爾運算快於位運算,越簡單的越靠前)

        使用System.arrayCopy()(native 函數)複製數組(31ms/250ms)

        Buffer進行I/O操作

        使用clone()代替new (一般是淺拷貝,其他需要具體實現clone)

        靜態方法代替實例方法

        

4. 並行程式開發及優化

    4.1 並行程式設計模式

        Future 模式 : 提高響應速度

        Master_worker 模式 : 子任務分配,提高響應速度 

        Guarded Suspension 模式 : 隊列緩衝,非立即處理,避免因為請求太多而崩潰

        不變模式 : 類似String/Double...不需要同步,線程安全

        生產者消費者模式 : 緩解兩者間的性能差

    4.2 JDK多任務執行框架

        無限制線程的缺陷

        簡單的線程池

        Exector 框架

        自定義線程池 : ThreadPoolExecutor

        優化線程池大小 : n = Ncpu * Ucpu *(1 +W/C)

        擴展 ThreadPoolExector

    4.3 JDK併發數據結構

        併發 list : CopyOnWriteArrayList

        併發 Set : CopyOnWriteArraySet

        併發 Map : ConcurrentHashMap

        併發 Queue : ConcurrentLinkedQueue (使用CAS無鎖) / LinkedBlockingQueue

        併發 Deque : LinkedBlockingDeque (讀寫都加鎖)

    4.4 併發控制方法 

        Java記憶體模型與 volatile

        同步關鍵字 synchronized

        ReentrantLock 重入鎖

        ReentrantReadWriteLock 讀寫鎖 (並讀串寫)

        Condition 對象

        Semaphore 信號量 (限制最大訪問線程數)

        ThreadLocal 線程局部變數

    4.5 鎖的性能和優化

        線程的開銷

        避免死鎖

        減小鎖持有時間

        減小鎖粒度

        讀寫分離鎖來替換獨占鎖

        鎖分離 (LinkedBlockingQueue)

        重入鎖 (ReentrantLock) 和內部鎖(Synchronized)

        鎖粗化 Lock Coarsening (多次重覆請求消耗資源)

        自旋鎖 Spinning Lock (執行空迴圈來減少被掛起的次數)

        鎖消除 Lock Elimination (消除不必要的鎖)

        鎖偏向 Biased Lock (高併發效率低)

    4.6 無鎖的並行計算

        非阻塞的同步/無鎖 (基於CAS)

        原子操作 (java.util.concurrent.atomic)

        Amino 框架 : 提供現成安全的,基於無鎖的數據結構,內置了多線程調度模式。 

        Amino 集合 : LockFreeList(linked)/LockFreeVector(ArrayList); LockFreeSet

        Amino 樹 : LockFreeBSTree(二叉搜索樹)

        Amino 圖 : UndirectedGraph<E> / DirectedGraph<E>

        Amino 簡單調度模式 : Master_worker (靜態/動態)

    4.7 協程

        協程的概念 : 進程的分割式線程,線程的分割是協程 

        Kilim 框架 : 當需要大量線程時,使用協程能提高性能,降低線程維護切換的性能

 

5. JVM調優

    5.1 Java 虛擬機記憶體模型

        程式計數器 : 線程私有的記憶體空間,互不影響; 當執行java方法,程式計數器為Java位元組碼地址,當執行native方法程式計數器為空

        Java虛擬機棧 : 線程私有的記憶體空間, 用於管理Java函數調用, -Xss1M

        本地方法棧 : 管理本地方法調用

        Java堆 : 分為新生代和老年代兩部分

        方法區 : 和Java堆一樣被所有線程共用;包括類的類型信息,常量池,域信息,方法信息,也叫永久區

    5.2 JVM 記憶體分配參數

        -Xmx : 設置最大堆記憶體

        -Xms : 設置初始堆記憶體

        -Xss : 設置線程棧 (使用系統記憶體,堆空間分配越大,線程總數越少) JDK5.0以後每個線程堆棧大小為1M,以前每個線程堆棧大小為256K

        -Xmn : 設置新生代 (一般為堆空間的1/4~1/3 )

        -XX:NewSize : 設置初始新生代空間

        -XX:MaxNewSize : 設置最大新生代空間    

        -XX:PermSize : 設置初始持久區

        -XX:MaxPermSize : 設置最大持久區

        -XX:SurvivorRatio 設置新生代比例 (eden : survivor) 

        -XX:NewRatio : 設置heap比例 (老年代 : 新生代) 

        -XX:TargetSurvivorRatio : 設置suvivior使用率,超過空間會送入老年代

    5.3 垃圾收集基礎

        垃圾收集的作用

        垃圾收集演算法與思想 

            1) 引用計演算法 : 記錄對象引用數,但兩個對象的迴圈引用會導致記憶體泄露

            2) 標記清除法 : 記錄根節點開始的可達對象,但回收後造成空間碎片

            3) 複製演算法 : 在存活對象少垃圾多的情況下,系統空間折半,複製有效對象到另一空間,適用於新生代對象(from space to space)

            4) 標記壓縮演算法 : 在存活對象多垃圾少的情況下,清除無效對象,壓縮有效對象,清除空間碎片,適用於老年代

            5) 增量演算法 : 避免長時間占據應用程式執行時間,而交替執行,每次清理一小片記憶體空間,但由於線程頻繁上下文切換,會降低系統吞吐量

            6) 分代 : 分為年輕代和老年代,分別使用不同的垃圾收集演算法,新生代使用複製演算法,老年代使用標記壓縮演算法

        垃圾收集器的類型 

            線程數 : 串列/並行

            工作模式 : 併發/獨占

            碎片處理 : 壓縮/非壓縮

            分代 : 新生代/老年代 

        評價GC策略的指標 : 吞吐量/垃圾回收器負載/停頓時間/垃圾回收頻率/反應時間/堆分配

        新生代串列收集器 : 單線程,獨占

        老年代串列收集器 : 標記壓縮,串列獨占

        並行收集器 : 多線程,獨占

        新生代並行回收收集器 : 多線程,獨占,關註系統吞吐量

        老年代並行回收收集器 : 標記壓縮,關註系統吞吐量

        CMS(concurrent Mark Sweep)收集器 :  標記清除法,多線程並行,非獨占

        G1(Garbage First)收集器 : 關註吞吐量和停頓控制,適用標記壓縮法

        Stop the World : 整個應用停止等待垃圾回收完成

        收集器對系統性能的影響

        GC相關參數總結

            1) 串列回收器相關參數

                -XX:+UseSerialGC : 新生代串列收集器和老年代串列收集器

                -XX:SurvivorRatio : 設置eden和survivor的比例

                -XX:PretenureSizeThreshold : 設置大對象進入老年代的閾值,對象大小超過此值,直接在老年代分配,只對串列收集器和新生代並行收集器有效,並行回收收集器不識別此參數

                -XX:MaxTenuringThreshold : 設置進入老年代的年齡最大值,每次Minor gc後,對象年齡+1, 預設15

            2) 並行回收器相關參數

                -XX:+UseParNewGC : 新生代使用並行收集器

                -XX:+UseParallelOldGC : 老年代使用並行回收收集器

                -XX:ParallelGCThreads : 垃圾回收線程數

                -XX:MaxGCPauseMillis :  最大垃圾收集停頓時間

                -XX:GCTimeRatio : 設置吞吐量大小n, GCTime < 1/(1+n)

                -XX:+UseAdaptiveSizePolicy : 打開自適應GC策略,新生代大小,eden和survivor比例等自動調整

            3) 與CMS回收器相關參數

                -XX:+UseConcMarkSweepGC : 新生代使用並行收集器,老年代使用CMS+串列收集器

                -XX:parallelCMSThreads : CMS的線程數量

                -XX:CMSInitiatingOccupancyFraction : 設置CMS收集器在老年代空間使用多少後觸發,預設68%

                -XX:+UseCMSCompactAtFullCollection : 設置CMS收集器在完成垃圾收集後是否進行一次記憶體碎片整理

                -XX:CMSFullGCsBeforeCompation : 設置多少次CMS垃圾回收後進行記憶體壓縮

                -XX:+CMSClassUnloadingEnabled : 允許對類元數據進行回收

                -XX:+CMSParallelRemarkEnabled : 啟用並行標記

                -XX:CMSInitiatingPermOccupancyFraction : 永久區達到此閾值,啟動CMS回收(前提是  -XX:CMSClassUnloadingEnabled激活)

                -XX:UseCMSInitiatingOccupancyOnly : 達到閾值才進行CMS回收

                -XX:+CMSIncrementalMode : 使用增量模式,適合單CPU

            4) 與G1回收器相關參數

                -XX:+UseG1GC : 使用G1回收器

                -XX:+UnlockExperimentalVMOptions : 允許使用實驗性參數

                -XX:MaxGCPauseMillis : 設置最大垃圾停頓時間

                -XX:GCPauseIntervalMillis :  設置垃圾收集間隔時間

            5) 其他參數

                -XX:+DisableExplicitGC : 禁用顯示GC

    5.4 常用調優案例和方法

        1) 將新對象預留在新生代 : 新生代的垃圾回收速度高於老年代回收,可設置新生代大小或者新生代和老年代比例調整新生代大小

        2) 大對象進入老年代 : 大對象需要空間,可能導致空間不足或者需要移動大量小對象到老年代,設置-XX:PretenureSizeThreshold

        3) 設置對象進入老年代的年齡 : gc一次年齡+1,年齡到達閾值進入老年代,設置閾值 -XX:MaxTenuringThreshold

        4) 穩定與震蕩的堆大小 : 空間大GC速度慢,空間小GC速度快,大部分設置最大最小相同

            -XX:MinHeapFreeRatio : 設置堆空間最小空閑比例,預設40;

            -XX:MaxHeapFreeRatio : 設置對空間最大空閑比例,預設70;

        5) 吞吐量優先案例 : java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC

        6) 使用大頁案例 : java -Xmx2506m -Xms2506 -Xmn1536m -Xss128k -XX:+UseParallelGC -XX:ParallelGCThreads=20 -XX:+UseParallelOldGC -XX:LargePageSizeInBytes=256m (設置大頁大小)

        7) 降低停頓案例 : java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC _XX:+UseParNewGC -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=31

    5.5 實用JVM參數

        1) JIT(Just-In-Time)編譯參數 : 運行時,函數運行次數超過閾值,將位元組碼編譯成本地代碼提高執行效率,

            -XX:CompileThreshold : 編譯閾值

            -XX:+PrintCompilation : 列印JIT編譯信息

            -XX:+CITime 列印JIT編譯的基本信息

        2) 堆快照(堆Dump) : 發生OOM時導出Dump文件,可以使用Visual VM等工具分析

            -XX:+HeapDumpOnOutOfMemoryError : 發生OOM時導出當前堆快照

            -XX:HeapDumpPath : 指定堆快照信息保存文件位置

        3) 錯誤處理 : 發生OOM時運行第三方腳本

            -XX:OnOutOfMemoryError=c:\reset.bat

        4) 取得GC信息

            -verbose:gc

            -XX:+PrintGC

            -XX:+PrintGCDetails

            -XX:+PrintGCTimeStamps : 列印每次GC的發生時間

            -XX:+PrintTenuringDistribution : 察看新生對象晉升老年代的實際閾值

            -XX:+PrintHeapAtGC : 每次GC列印堆的使用情況

            -XX:+PrintGCApplicationStoppedTime : 顯示應用程式在GC發生時的停頓時間

            -XX:+PrintGCApplicationConcurrentTime : 應用程式在GC停頓時間的執行時間

            -Xloggc:C:\gc.log : GC日誌

        5) 類和對象跟蹤

            -XX:+TraceClassLoading : 跟蹤類載入情況

            -XX:+TraceClassUnloading : 跟蹤類的卸載情況

            -verbose:class :  跟蹤類的載入和卸載情況

            -XX:+PrintClassHistogram : 當按下Ctrl + Break,輸出系統內類的統計信息

        6) 控制GC

            -XX:DisableExplicitGC : 禁止顯示GC操作,避免程式員大量使用System.gc()降低程式性能

            -Xnoclassgc : 禁止回收類(class,而不是對象實例)

        7) 選擇類校驗器

            -XX:-UseSplitVerifier :實用舊的類校驗器,JDK1.6預設開啟新的類校驗器

            -XX:-FailOverToOldVerifier : 關閉再次校驗功能, 預設新的校驗器失敗會再次使用老的校驗器

        8) Solaris下線程式控制制

            -XX:+UseBoundThreads : 綁定所有用戶線程到內核線程,減少線程進入饑餓狀態的次數

            -XX:+UseLWPSychronization : 使用內核線程代替線程同步

            -XX:+UseVMInterruptibleIO : 允許運行時中斷線程

        9) 使用大頁

            -XX:+UseLargePages : 啟用大頁

            -XX:LargePageSizeInBytes : 指定大頁的大小

        10) 壓縮指針

            -XX:+UseCompressedOops : 打開指針壓縮,壓縮class的屬性指針(靜態成員),對象的屬性指針,普通對象的每個元素指針, 能節省記憶體,但是會消耗一定的性能

    5.6 實戰JVM調優

        1) Tomcat簡介與啟動加速 : 減少GC次數,擴大新生代,禁止顯示調用GC

        2) 一個示例web : 每個用戶分配1m空間

        3) JMEter介紹和使用 : 基於java的性能測試和壓力測試工具,生成包括響應時間,錯誤數和吞吐量的報告

        4) 調優前Web應用運行狀況 : GC過多,吞吐量為38.7/s

        5) 調優過程 : 確定堆記憶體大小,合理分配新生代和老年代,確定永久區大小,選擇垃圾收集器,對垃圾收集器設置,禁用顯示gc,進用類元數據回收,禁用類驗證等

            設置堆空間和永久區,禁用顯示gc,去掉類驗證,吞吐量為47.9/s

            -Xmx512M(-Xmx256M)

            -Xms512M

            -XX:permSize=32M

            -XX:MaxPermSize=32M

            -XX:+DisableExplicitGC

            -Xverify:none

            使用並行回收收集器,吞吐量為51/s

            -XX:+UseParallelGC

            -XX:+UseParallelOldGC

            -XX:ParallelGCThreads=8

6 Java性能調優工具

    6.1 Linux命令行工具

        1) top : 顯示系統中各個進程的資源占用狀況

        2) sar : 周期性對記憶體,I/O和CPU情況採樣 

        3) vmstat : 統計CPU記憶體使用情況,swap使用情況,可指定周期性採樣和次數

        4) iostat : 提供詳盡的I/O信息,可指定周期性採樣和次數

        6) pidstat : 監測進程和線程的情況,

            監測CPU : 可以配合 jstack -l $ThreadId 察看進程堆棧

            I/O使用監控 

            記憶體監控

    6.2 Windows工具

        1) 任務管理器 

        2) perfmon性能檢測工具 : 可以針對一個進程進行監控

        3) Process Explorer : 需安裝

        4) pslist  : 需安裝

    6.3 JDK命令行工具

        1) jps : 類似Linux下的ps,用於列出Java進程,-m(主函數的參數),-l(主函數路徑),-v(顯示JVM參數)

        2) jstat : 觀察Java應用程式運行時的信息

        3) jinfo : 察看Java應用程式的擴展參數(JVM參數),可通過此命令來查看預設參數值,可修改參數 

        4) jmap : 生成堆快照和對象的統計信息

        5) jhat : 分析Java應用程式的對快照內容,可在瀏覽器中訪問http://127.0.0.1:7000

        6) jstack : 導出Java應用車功能需的線程堆棧

        7) jstatd : RMI的服務端程式,建立遠程監控通信,需要使用java的安全策略在使用

        8) hprof : 非獨立監控工具,用於監測Java程式的CPUh和堆信息,監控函數運行時間,導出程式堆內容

    6.4 JConsole工具 : %javahome%/bin/jconsole.exe

        1) JConsole連接Java程式 : 添加啟動參數可遠程連接

            -Dcom.sun.management.jmxremote.authenticate=false  -Dcom.sun.management.jmxremote.ssl=fals  -Dcom.sun.management.jmxremote.port=9988 -Dcom.sun.management.jmxremote

        2) Java程式概況 : 可查看堆記憶體,系統線程數量,載入類數量和CPU使用率

        3) 記憶體監控 : 察看記憶體詳細信息,細化到eden,survivior,老年代,永久區;可以強制Full GC

        4) 線程監控 : 可以監測到所有線程以及棧信息

        5) 類載入情況 : 顯示載入空間,類數量

        6) 虛擬機信息 : 顯示虛擬機類型,版本,堆信息,虛擬機參數

        7) MBean管理 : 可操作GC信息顯示,線程信息查看,峰值線程數量,當前線程數量,死鎖檢測等 

        8) 使用插件 : 如JDK自帶插件JTop,察看線程CPU使用排序

    6.5 Visual VM多合一工具

        1) Visual VM連接應用程式 : 添加JVM參數或者配合jstatd遠程監控

        2) 監控應用程式概況 : 類似Jconsole

        3) Thead Dump和分析 

        4) 性能分析 : 在Sampler頁面下,可以監測方法調用時間

        5) 快照 : 快照導出 

        6) 記憶體快照分析 

        7) MBean管理 : 可通過插件繼承MBean

        8) TDA使用 : 分析導出的線程快照,可以單獨運行,也可以作為Visual VM插件運行

        9) BTrace介紹 : 在不停機的情況下添加代碼執行,

            監控指定函數耗時 

            取得任意行代碼信息

            定時觸發

            監控函數參數

            監控文件

    6.6 Visual VM對OQL的支持

        1) Visual VM的OQL基本語法

        2) 內置head對象 

        3) 對象函數

        4) 集合/統計函數 

        5) 程式化OQL

    6.7 MAT記憶體工具分析

    6.8 MAT對OQL的支持

    6.9 JProfile簡介 : 商業軟體

    

        

JVM :      -XX:+UseSpinning (開啟自旋鎖) -XX:PreBlockSpin (自旋鎖的等待次數)        

        -server -XX:+DoEscapeAnalysis (逃逸分析) -XX:+EliminateLocks (鎖消除)

        -XX:+UseBiasedLocking (開啟偏向鎖)

        -Xss1M

        -XX:+PrintGCDetails(輸出收集器日誌)

        -XX:+UseSerialGC (新生代串列收集器和老年代串列收集器)

        -XX:+UseParallelGC (新生代並行回收收集器和老年代串列收集器,會停止app threads)

        -XX:+UseParNewGC (新生代並行收集器和老年代串列收集器)

        -XX:+UseConcMarkSweepGC (新生代並行收集器和老年代CMS)

            -XX:CMSInitiatingOccupancyFraction (CMS老年代回收閥值n,預設68(%),如果記憶體使用增長快,n較小時效率高,反之n應該較大)

            -XX:+UseCMSCompactAtFullCollection (CMS收集完成進行碎片整理,整理不是併發進行)

            -XX:CMSFullGCsBeforeCompation (CMS進行n次後,才進行記憶體壓縮)

        -XX:+UseParallelOldGC (新生代老年代並行回收處理器) 

            -XX:MaxGCPauseMillis (最大垃圾收集停頓時間) 

            -XX:GCTimeRatio (設置吞吐量大小 : n=[0~100] (gcTime <= 1/(1+n) ) ) 

            -XX:+UseAdaptiveSizePolicy (自適應GC調節策略) 

            -XX:ParallelGCThreads (收集器線程數,一般等於CPU數量)

        -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC (啟動G1 GC)

            -XX:MaxGCPauseMillis -XX:GCPauseIntervalMillis (不超過200ms, 停頓不超過50ms,參數只是目標,不保證執行)

        -XX:DisableExplicitGC (禁用顯示gc) -Xnoclassgc(禁用類元數據回收) -Xverify:none (禁用類驗證)

        

        

remote debug : 遠程debug 

    遠程debug顧名思義,能夠將遠程操作系統上的任何java進行debug,但是有前提是本地需要有同步的代碼。

    1.遠程debug的步驟是在遠程操作系統上啟動java進程時增加特殊的

        -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=9977

    2.在Eclipse中新建一個Remote Java Application


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 談起 Hibernate 應該得知道 Gavin King 大叔,他構建了 Hibernate ,並將其捐獻給了開源社區。 Hibernate 對象關係映射解決方案,為面向對象的領域模型到傳統的關係型資料庫的映射,提供了一個使用方便的框架。 Hibernate 的設計目標是將軟體開發人員從大量相同的 ...
  • s1=set([11,22,33,44,'Tom','tony',11,77,2.5,])返回的是{11,22,33,44,‘Tom’,‘tony’,77,2.5}(註意:返回的並不是一個字典,只是告訴你這個集合中含有這些元素,所以每次返回的結果元素的順序可能是不一樣的) s2=set([11,22 ...
  • 1 項目中程式調用發信息的介面時候,直接調用可能出現錯誤,影響主程式的流程; 解決:(1)mq發送消息 (2)發消息的介面自身捕獲處理異常,不能拋出到主程式中 現在針對第二種解決方案進行實現:因為以前各個發消息的節點都是拋出異常,如果針對每個方法都加上異常處理會很麻煩,現在用spring提供的@As ...
  • -------說明-------- IBatis 版本2.0 配置一對多 namespace = testDao ------------------ /** *班級的resultMap *ClassBean 對應的bean 例如org.test.ClassBean *id 為唯一的標識 */ //... ...
  • 前言:最近需要做一套CMS系統,由於功能比較單一,而且要求靈活,所以放棄了WP這樣的成熟系統,自己做一套相對簡單一點的。文章的詳情頁URL想要做成url偽靜態的格式即xxx.html 其中xxx考慮過直接用自增主鍵,但是感覺這樣有點暴露文章數量,有同學說可以把初始值設高一點,可是還是可以通過ID差算 ...
  • 本文地址 分享提綱: 1.概述 2. 原理 3. 安裝 4. 使用 5. 參考文檔 1. 概述 1.1)【常見文件系統】 Google了一下,流行的開源分散式文件系統有很多,介紹如下: -- mogileFS:Key-Value型元文件系統,不支持FUSE,應用程式訪問它時需要API,主要用在web ...
  • Windos環境用Nginx配置反向代理和負載均衡 引言:在前後端分離架構下,難免會遇到跨域問題。目前的解決方案大致有JSONP,反向代理,CORS這三種方式。JSONP相容性良好,最大的缺點是只支持GET方式請求。反向代理方式簡單徹底,基本只需要伺服器配置即可完成。CORS由服務提供程式主動聲明自 ...
  • RabbitMq應用一 RabbitMQ的具體概念,百度百科一下,我這裡說一下我的理解,如果有少或者不對的地方,歡迎糾正和補充。 一個項目架構,小的時候,一般都是傳統的單一網站系統,或者項目,三層架構,到現在的MVC架構。隨著用戶訪問量越來越多,系統業務越來越多,會出現以下問題: 1.修改完大量代碼 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...