我的Java路上那些事兒

          快樂(lè)成長(zhǎng)
          posts - 110, comments - 101, trackbacks - 0, articles - 7
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          2013年11月26日

          轉(zhuǎn)自:http://blog.csdn.net/jeffreynicole/article/details/46953059 


          一個(gè)性能較好的web服務(wù)器jvm參數(shù)配置:


          1. -server //服務(wù)器模式  
          2. -Xmx2g //JVM最大允許分配的堆內(nèi)存,按需分配  
          3. -Xms2g //JVM初始分配的堆內(nèi)存,一般和Xmx配置成一樣以避免每次gc后JVM重新分配內(nèi)存。  
          4. -Xmn256m //年輕代內(nèi)存大小,整個(gè)JVM內(nèi)存=年輕代 + 年老代 + 持久代  
          5. -XX:PermSize=128m //持久代內(nèi)存大小  
          6. -Xss256k //設(shè)置每個(gè)線程的堆棧大小  
          7. -XX:+DisableExplicitGC //忽略手動(dòng)調(diào)用GC, System.gc()的調(diào)用就會(huì)變成一個(gè)空調(diào)用,完全不觸發(fā)GC  
          8. -XX:+UseConcMarkSweepGC //并發(fā)標(biāo)記清除(CMS)收集器  
          9. -XX:+CMSParallelRemarkEnabled //降低標(biāo)記停頓  
          10. -XX:+UseCMSCompactAtFullCollection //在FULL GC的時(shí)候?qū)δ昀洗膲嚎s  
          11. -XX:LargePageSizeInBytes=128m //內(nèi)存頁(yè)的大小  
          12. -XX:+UseFastAccessorMethods //原始類型的快速優(yōu)化  
          13. -XX:+UseCMSInitiatingOccupancyOnly //使用手動(dòng)定義初始化定義開(kāi)始CMS收集  
          14. -XX:CMSInitiatingOccupancyFraction=70 //使用cms作為垃圾回收使用70%后開(kāi)始CMS收集  


          說(shuō)明:

          -Xmn和-Xmx之比大概是1:9,如果把新生代內(nèi)存設(shè)置得太大會(huì)導(dǎo)致young gc時(shí)間較長(zhǎng)

          一個(gè)好的Web系統(tǒng)應(yīng)該是每次http請(qǐng)求申請(qǐng)內(nèi)存都能在young gc回收掉,full gc永不發(fā)生,當(dāng)然這是最理想的情況

          xmn的值應(yīng)該是保證夠用(夠http并發(fā)請(qǐng)求之用)的前提下設(shè)置得盡量小

          web服務(wù)器和游戲服務(wù)器的配置思路不太一樣,最重要的區(qū)別是對(duì)游戲服務(wù)器的xmn即年輕代設(shè)置比較大,和Xmx大概1:3的關(guān)系,因?yàn)橛螒蚍?wù)器一般是長(zhǎng)連接,在保持一定的并發(fā)量后需要較大的年輕代堆內(nèi)存,如果設(shè)置得大小了會(huì)經(jīng)常引發(fā)young gc


          • 對(duì)JVM的簡(jiǎn)介


          由上圖可以看出jvm堆內(nèi)存的分類情況,JVM內(nèi)存被分成多個(gè)獨(dú)立的部分。
          廣泛地說(shuō),JVM堆內(nèi)存被分為兩部分——年輕代(Young Generation)和老年代(Old Generation)。


          • 年輕代
          年輕代是所有新對(duì)象產(chǎn)生的地方。當(dāng)年輕代內(nèi)存空間被用完時(shí),就會(huì)觸發(fā)垃圾回收。這個(gè)垃圾回收叫做Minor GC。年輕代被分為3個(gè)部分——Enden區(qū)和兩個(gè)Survivor區(qū)。


          年輕代空間的要點(diǎn):
          大多數(shù)新建的對(duì)象都位于Eden區(qū)。
          當(dāng)Eden區(qū)被對(duì)象填滿時(shí),就會(huì)執(zhí)行Minor GC。并把所有存活下來(lái)的對(duì)象轉(zhuǎn)移到其中一個(gè)survivor區(qū)。
          Minor GC同樣會(huì)檢查存活下來(lái)的對(duì)象,并把它們轉(zhuǎn)移到另一個(gè)survivor區(qū)。這樣在一段時(shí)間內(nèi),總會(huì)有一個(gè)空的survivor區(qū)。
          經(jīng)過(guò)多次GC周期后,仍然存活下來(lái)的對(duì)象會(huì)被轉(zhuǎn)移到年老代內(nèi)存空間。通常這是在年輕代有資格提升到年老代前通過(guò)設(shè)定年齡閾值來(lái)完成的。

          • 年老代
          年老代內(nèi)存里包含了長(zhǎng)期存活的對(duì)象和經(jīng)過(guò)多次Minor GC后依然存活下來(lái)的對(duì)象。通常會(huì)在老年代內(nèi)存被占滿時(shí)進(jìn)行垃圾回收。老年代的垃圾收集叫做Major GC。Major GC會(huì)花費(fèi)更多的時(shí)間。


          Stop the World事件
          所有的垃圾收集都是“Stop the World”事件,因?yàn)樗械膽?yīng)用線程都會(huì)停下來(lái)直到操作完成(所以叫“Stop the World”)。

          因?yàn)槟贻p代里的對(duì)象都是一些臨時(shí)(short-lived )對(duì)象,執(zhí)行Minor GC非??欤詰?yīng)用不會(huì)受到(“Stop the World”)影響。

          由于Major GC會(huì)檢查所有存活的對(duì)象,因此會(huì)花費(fèi)更長(zhǎng)的時(shí)間。應(yīng)該盡量減少M(fèi)ajor GC。因?yàn)镸ajor GC會(huì)在垃圾回收期間讓你的應(yīng)用反應(yīng)遲鈍,所以如果你有一個(gè)需要快速響應(yīng)的應(yīng)用發(fā)生多次Major GC,你會(huì)看到超時(shí)錯(cuò)誤。

          垃圾回收時(shí)間取決于垃圾回收策略。這就是為什么有必要去監(jiān)控垃圾收集和對(duì)垃圾收集進(jìn)行調(diào)優(yōu)。從而避免要求快速響應(yīng)的應(yīng)用出現(xiàn)超時(shí)錯(cuò)誤。


          • 永久代
          永久代或者“Perm Gen”包含了JVM需要的應(yīng)用元數(shù)據(jù),這些元數(shù)據(jù)描述了在應(yīng)用里使用的類和方法。注意,永久代不是Java堆內(nèi)存的一部分。
          永久代存放JVM運(yùn)行時(shí)使用的類。永久代同樣包含了Java SE庫(kù)的類和方法。永久代的對(duì)象在full GC時(shí)進(jìn)行垃圾收集。


          方法區(qū)
          方法區(qū)是永久代空間的一部分,并用來(lái)存儲(chǔ)類型信息(運(yùn)行時(shí)常量和靜態(tài)變量)和方法代碼和構(gòu)造函數(shù)代碼。


          內(nèi)存池
          如果JVM實(shí)現(xiàn)支持,JVM內(nèi)存管理會(huì)為創(chuàng)建內(nèi)存池,用來(lái)為不變對(duì)象創(chuàng)建對(duì)象池。字符串池就是內(nèi)存池類型的一個(gè)很好的例子。內(nèi)存池可以屬于堆或者永久代,這取決于JVM內(nèi)存管理的實(shí)現(xiàn)。


          運(yùn)行時(shí)常量池
          運(yùn)行時(shí)常量池是每個(gè)類常量池的運(yùn)行時(shí)代表。它包含了類的運(yùn)行時(shí)常量和靜態(tài)方法。運(yùn)行時(shí)常量池是方法區(qū)的一部分。


          Java棧內(nèi)存
          Java棧內(nèi)存用于運(yùn)行線程。它們包含了方法里的臨時(shí)數(shù)據(jù)、堆里其它對(duì)象引用的特定數(shù)據(jù)。

          Java垃圾回收
          Java垃圾回收會(huì)找出沒(méi)用的對(duì)象,把它從內(nèi)存中移除并釋放出內(nèi)存給以后創(chuàng)建的對(duì)象使用。Java程序語(yǔ)言中的一個(gè)最大優(yōu)點(diǎn)是自動(dòng)垃圾回收,不像其他的程序語(yǔ)言那樣需要手動(dòng)分配和釋放內(nèi)存,比如C語(yǔ)言。

          垃圾收集器是一個(gè)后臺(tái)運(yùn)行程序。它管理著內(nèi)存中的所有對(duì)象并找出沒(méi)被引用的對(duì)象。所有的這些未引用的對(duì)象都會(huì)被刪除,回收它們的空間并分配給其他對(duì)象。

          一個(gè)基本的垃圾回收過(guò)程涉及三個(gè)步驟:
          標(biāo)記:這是第一步。在這一步,垃圾收集器會(huì)找出哪些對(duì)象正在使用和哪些對(duì)象不在使用。
          正常清除:垃圾收集器清會(huì)除不在使用的對(duì)象,回收它們的空間分配給其他對(duì)象。
          壓縮清除:為了提升性能,壓縮清除會(huì)在刪除沒(méi)用的對(duì)象后,把所有存活的對(duì)象移到一起。這樣可以提高分配新對(duì)象的效率。


          簡(jiǎn)單標(biāo)記和清除方法存在兩個(gè)問(wèn)題:
          效率很低。因?yàn)榇蠖鄶?shù)新建對(duì)象都會(huì)成為“沒(méi)用對(duì)象”。
          經(jīng)過(guò)多次垃圾回收周期的對(duì)象很有可能在以后的周期也會(huì)存活下來(lái)。
          上面簡(jiǎn)單清除方法的問(wèn)題在于Java垃圾收集的分代回收的,而且在堆內(nèi)存里有年輕代和年老代兩個(gè)區(qū)域。


          • Java垃圾回收類型
          這里有五種可以在應(yīng)用里使用的垃圾回收類型。

          僅需要使用JVM開(kāi)關(guān)就可以在我們的應(yīng)用里啟用垃圾回收策略。

          Serial GC(-XX:+UseSerialGC):Serial GC使用簡(jiǎn)單的標(biāo)記、清除、壓縮方法對(duì)年輕代和年老代進(jìn)行垃圾回收,即Minor GC和Major GC。Serial GC在client模式(客戶端模式)很有用,比如在簡(jiǎn)單的獨(dú)立應(yīng)用和CPU配置較低的機(jī)器。這個(gè)模式對(duì)占有內(nèi)存較少的應(yīng)用很管用。
          Parallel GC(-XX:+UseParallelGC):除了會(huì)產(chǎn)生N個(gè)線程來(lái)進(jìn)行年輕代的垃圾收集外,Parallel GC和Serial GC幾乎一樣。這里的N是系統(tǒng)CPU的核數(shù)。我們可以使用 -XX:ParallelGCThreads=n 這個(gè)JVM選項(xiàng)來(lái)控制線程數(shù)量。并行垃圾收集器也叫throughput收集器。因?yàn)樗褂昧硕郈PU加快垃圾回收性能。Parallel GC在進(jìn)行年老代垃圾收集時(shí)使用單線程。
          Parallel Old GC(-XX:+UseParallelOldGC):和Parallel GC一樣。不同之處,Parallel Old GC在年輕代垃圾收集和年老代垃圾回收時(shí)都使用多線程收集。
          并發(fā)標(biāo)記清除(CMS)收集器(-XX:+UseConcMarkSweepGC):CMS收集器也被稱為短暫停頓并發(fā)收集器。它是對(duì)年老代進(jìn)行垃圾收集的。CMS收集器通過(guò)多線程并發(fā)進(jìn)行垃圾回收,盡量減少垃圾收集造成的停頓。CMS收集器對(duì)年輕代進(jìn)行垃圾回收使用的算法和Parallel收集器一樣。這個(gè)垃圾收集器適用于不能忍受長(zhǎng)時(shí)間停頓要求快速響應(yīng)的應(yīng)用。可使用 -XX:ParallelCMSThreads=n JVM選項(xiàng)來(lái)限制CMS收集器的線程數(shù)量。
          G1垃圾收集器(-XX:+UseG1GC) G1(Garbage First):垃圾收集器是在Java 7后才可以使用的特性,它的長(zhǎng)遠(yuǎn)目標(biāo)時(shí)代替CMS收集器。G1收集器是一個(gè)并行的、并發(fā)的和增量式壓縮短暫停頓的垃圾收集器。G1收集器和其他的收集器運(yùn)行方式不一樣,不區(qū)分年輕代和年老代空間。它把堆空間劃分為多個(gè)大小相等的區(qū)域。當(dāng)進(jìn)行垃圾收集時(shí),它會(huì)優(yōu)先收集存活對(duì)象較少的區(qū)域,因此叫“Garbage First”。

          posted @ 2015-07-19 22:57 云云 閱讀(1212) | 評(píng)論 (0)編輯 收藏

          posted @ 2014-09-28 23:45 云云| 編輯 收藏

               摘要: class文件簡(jiǎn)介及加載     Java編譯器編譯好Java文件之后,產(chǎn)生.class 文件在磁盤中。這種class文件是二進(jìn)制文件,內(nèi)容是只有JVM虛擬機(jī)能夠識(shí)別的機(jī)器碼。JVM虛擬機(jī)讀取字節(jié)碼文件,取出二進(jìn)制數(shù)據(jù),加載到內(nèi)存中,解析.class 文件內(nèi)的信息,生成對(duì)應(yīng)的 Class對(duì)象:     &nb...  閱讀全文

          posted @ 2014-09-28 23:44 云云| 編輯 收藏

           
          package com.qiyi.appstore.util;
          import java.lang.reflect.Field;
          import java.lang.reflect.InvocationTargetException;
          import org.apache.commons.beanutils.BeanUtils;
          import org.apache.commons.lang.StringUtils;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          import com.qiyi.appstore.exception.AppStoreException;
          import com.qiyi.cloud.user.ApiCode;
          public class XssUtils {
          private static final Logger logger=LoggerFactory.getLogger(XssUtils.class);
          public static String getSafeStringXSS(String s){
                if (StringUtils.isBlank(s)) {  
                    return s;  
                }  
                StringBuilder sb = new StringBuilder(s.length() + 16);  
                for (int i = 0; i < s.length(); i++) {  
                    char c = s.charAt(i);  
                    switch (c) {  
                    case '<':  
                        sb.append("&lt;");  
                        break; 
                    case '>':  
                        sb.append("&gt;");  
                        break;  
                    case '\'':  
                        sb.append("&prime;");// &acute;");  
                        break;  
                    case '′':  
                        sb.append("&prime;");// &acute;");  
                        break;  
                    case '\"':  
                        sb.append("&quot;");  
                        break;  
                    case '"':  
                        sb.append("&quot;");  
                        break;  
                    case '&':  
                        sb.append("&");  
                        break;  
                    case '#':  
                        sb.append("#");  
                        break;  
                    case '\\':  
                        sb.append('¥');  
                        break; 
                    case '=':  
                        sb.append("=");  
                        break;
                    default:  
                        sb.append(c);  
                        break;  
                    }  
                }  
                return sb.toString(); 
            }
          public static <T> void getXssSaftBean(Class<?> clz,T bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException{
          String classname = clz.getSimpleName();
          logger.info("map target class name is {} .",classname);
          Field[] fields = clz.getDeclaredFields();
          for(Field field : fields){
          Class<?> type = field.getType();
          if(type.equals(String.class)){
          String fieldname = field.getName();
          String value = BeanUtils.getProperty(bean, fieldname);
          if(StringUtils.isNotBlank(value)){
          BeanUtils.setProperty(bean, fieldname, getSafeStringXSS(value));
          }
          }
          }
          }
          }

          posted @ 2014-09-28 13:49 云云 閱讀(732) | 評(píng)論 (0)編輯 收藏

          提升tomcat 性能 apr擴(kuò)展lib
          使用apr類庫(kù) 可以讓tomcat的性能提升到3到4倍  
          目前項(xiàng)目中都使用這樣的配置
          <Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" URIEncoding="UTF-8"
                         enableLookups="false"
                         acceptCount="300"
                         connectionTimeout="20000"
                         disableUploadTimeout="true" maxThreads="1000" maxSpareThreads="50" minSpareThreads="25"
                         redirectPort="8443" />


          catalia.sh 
          CATALINA_OPTS="$CATALINA_OPTS -Djava.library.path=/usr/local/apr/lib"

          posted @ 2014-01-16 14:50 云云 閱讀(917) | 評(píng)論 (0)編輯 收藏

               摘要: public static boolean acquireLock(String lock) {    // 1. 通過(guò)SETNX試圖獲取一個(gè)lock    boolean success = false;    Jedis jedis = pool.getResource();...  閱讀全文

          posted @ 2014-01-15 19:00 云云 閱讀(13408) | 評(píng)論 (1)編輯 收藏

          對(duì)eclipse的默認(rèn)配置很不爽,黑色字體白色底好刺眼,而且字體習(xí)慣用Courier New
          改變背景顏色:
          windows->Preferences->General->Editor->Text Editors
          右邊選擇Appearance color options 
          選Background color 選擇背景顏色
          個(gè)人比較舒服的豆沙綠色和黑色背景,但黑色背景還要把其他的字體顏色也改了才好看,而且豆沙綠色跟默認(rèn)的字體顏色搭配的很好。
          豆沙綠色(色調(diào):85   飽和度:123   亮度:205 )
          據(jù)說(shuō)這個(gè)色調(diào)是眼科專家配的, 因其顏色比較柔和,據(jù)說(shuō)閱讀的時(shí)候用這種顏色做背景有利于保護(hù)眼睛, word底色就許多人設(shè)置成豆沙綠色。
          xml的字體調(diào)整: 
          window--preferences--General--appearance--colors and fonts--Basic-- "Text font "  
          然后點(diǎn)change,可以設(shè)置字體,我喜歡Courier New
          Java的字體調(diào)整: 
          window--preferences--General--appearance--colors and fonts--java 

          posted @ 2014-01-09 16:41 云云 閱讀(1816) | 評(píng)論 (0)編輯 收藏

          有時(shí)候在項(xiàng)目中 會(huì)變化路徑 把原有路徑的文件拷到新的路徑下面
          再刪除原來(lái)不想的路徑再提交一次 這樣以來(lái) 原來(lái)的路徑確實(shí)不存在了
          但是拷過(guò)來(lái)的文件帶有原來(lái)路徑的svn信息 這樣以來(lái) 在提交的時(shí)候 就無(wú)法提交
          想要文件按照的路徑提交 但始終svn還是再往以前的路徑提交 并提示你路徑不存在
          在網(wǎng)上搜了下 如何刪除文件自帶的svn路徑信息
          按照下面的方式來(lái)操作即可

          Windows Registry Editor Version 5.00
          [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] 
          @="刪除該目錄下面.svn文件"
          [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command] 
          @="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""


          把上面這段文字保存問(wèn)一個(gè)Done.reg文件
          然后執(zhí)行,導(dǎo)入到注冊(cè)表
          就會(huì)在你右鍵一個(gè)文件夾的時(shí)候多出來(lái)一個(gè)菜單"刪除該目錄下面.svn文件"
          執(zhí)行該命令即可

           

          posted @ 2013-12-05 17:17 云云 閱讀(726) | 評(píng)論 (0)編輯 收藏

          在ibatis中不需要關(guān)注這些參數(shù) 而轉(zhuǎn)到mybatis后 如果字段值為空 必須設(shè)置jdbcType

          insert into testTable
             (ID,
             NAME,
             DESCRIPTION,
             IMAGEURL,
             LINKURL,
             ISALWAYS,
             ISDISPLAYINDEX,
             DISPLAYWEIGHT,
             STARTTIME,
             ENDTIME,
             CREATOR,
             CREATTIME,
             MODIFYTIME)
            values
             (SEQ_ACTIVITY_TABLE.NEXTVAL,
             #{name},
             #{desc,jdbcType=VARCHAR},
             #{imageUrl,jdbcType=VARCHAR},
             #{linkUrl,jdbcType=VARCHAR},
             #{isAlways,jdbcType=CHAR},
             #{isDisplayIndex,jdbcType=CHAR},
             #{displayWeight,jdbcType=VARCHAR},
             #{startTime,jdbcType=DATE},
             #{endTime,jdbcType=DATE},
             #{creator,jdbcType=VARCHAR},
             sysdate,
             sysdate
             )
           </insert>

          這些設(shè)置之多,太煩了,最讓人煩的是  jdbcType = DATE,類型還必須大寫(xiě),不能小寫(xiě)。
          如下面的例子,將DATE 改成 Date 。結(jié)果讓人很抓狂?。。?!
          insert into testTable
             (ID,
             NAME,
             DESCRIPTION,
             IMAGEURL,
             LINKURL,
             ISALWAYS,
             ISDISPLAYINDEX,
             DISPLAYWEIGHT,
             STARTTIME,
             ENDTIME,
             CREATOR,
             CREATTIME,
             MODIFYTIME)
            values
             (SEQ_ACTIVITY_TABLE.NEXTVAL,
             #{name},
             #{desc,jdbcType=VARCHAR},
             #{imageUrl,jdbcType=VARCHAR},
             #{linkUrl,jdbcType=VARCHAR},
             #{isAlways,jdbcType=CHAR},
             #{isDisplayIndex,jdbcType=CHAR},
             #{displayWeight,jdbcType=VARCHAR},
             #{startTime,jdbcType=Date},
             #{endTime,jdbcType=DATE},
             #{creator,jdbcType=VARCHAR},
             sysdate,
             sysdate
             )
           </insert>
          org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error resolving JdbcType. Cause: java.lang.IllegalArgumentException: No enum const class org.apache.ibatis.type.JdbcType.Date
          	org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
          	org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:368)
          更坑爹的在后面,上面insert時(shí)的時(shí)候用#{endTime,jdbcType=DATE},可以將時(shí)間插入成功,且可以精確到時(shí)分秒
          但如果在update語(yǔ)句中也這樣使用,那你得到的只會(huì)有日期,這夠坑爹的了吧 ,尼瑪  比起ibatis方便之處差遠(yuǎn)了
          要想在update語(yǔ)句中 將時(shí)間格式化成時(shí)分秒 不得不再加一個(gè)類型 如下面:
          startTime = #{startTime,javaType=DATE, jdbcType=VARCHAR}













          posted @ 2013-11-26 21:02 云云 閱讀(21436) | 評(píng)論 (1)編輯 收藏

          主站蜘蛛池模板: 钦州市| 齐河县| 孝义市| 昌宁县| 乐昌市| 那曲县| 孙吴县| 鹿泉市| 富阳市| 秀山| 濮阳县| 六枝特区| 静乐县| 白城市| 宜君县| 泾阳县| 沙湾县| 托克逊县| 崇仁县| 黄龙县| 仲巴县| 聂荣县| 巴南区| 亳州市| 阿克| 墨竹工卡县| 昭苏县| 黔江区| 呼和浩特市| 中方县| 方山县| 射洪县| 汾西县| 龙陵县| 黎城县| 黄石市| 麻江县| 津南区| 乌海市| 临朐县| 西林县|