posts - 110, comments - 101, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2013年11月26日

转自:http://blog.csdn.net/jeffreynicole/article/details/46953059 


一个性能较好的web服务器jvm参数配置:


  1. -server //服务器模式  
  2. -Xmx2g //JVM最大允许分配的堆内存,按需分配  
  3. -Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次gc后JVM重新分配内存。  
  4. -Xmn256m //年轻代内存大小,整个JVM内存=年轻代 + 年老代 + 持久代  
  5. -XX:PermSize=128m //持久代内存大小  
  6. -Xss256k //设置每个线程的堆栈大小  
  7. -XX:+DisableExplicitGC //忽略手动调用GC, System.gc()的调用就会变成一个空调用,完全不触发GC  
  8. -XX:+UseConcMarkSweepGC //并发标记清除(CMS)收集器  
  9. -XX:+CMSParallelRemarkEnabled //降低标记停顿  
  10. -XX:+UseCMSCompactAtFullCollection //在FULL GC的时候对年老代的压缩  
  11. -XX:LargePageSizeInBytes=128m //内存页的大小  
  12. -XX:+UseFastAccessorMethods //原始类型的快速优化  
  13. -XX:+UseCMSInitiatingOccupancyOnly //使用手动定义初始化定义开始CMS收集  
  14. -XX:CMSInitiatingOccupancyFraction=70 //使用cms作为垃圾回收使用70%后开始CMS收集  


说明:

-Xmn和-Xmx之比大概是1:9,如果把新生代内存设置得太大会导致young gc时间较长

一个好的Web系统应该是每次http请求申请内存都能在young gc回收掉,full gc永不发生,当然这是最理想的情况

xmn的值应该是保证够用(够http并发请求之用)的前提下设置得尽量小

web服务器和游戏服务器的配置思路不太一样,最重要的区别是对游戏服务器的xmn即年轻代设置比较大,和Xmx大概1:3的关系,因为游戏服务器一般是长连接,在保持一定的并发量后需要较大的年轻代堆内存,如果设置得大小了会经常引发young gc


  • 对JVM的简介


由上图可以看出jvm堆内存的分类情况,JVM内存被分成多个独立的部分。
广泛地说,JVM堆内存被分为两部分——年轻代(Young Generation)和老年代(Old Generation)。


  • 年轻代
年轻代是所有新对象产生的地方。当年轻代内存空间被用完时,就会触发垃圾回收。这个垃圾回收叫做Minor GC。年轻代被分为3个部分——Enden区和两个Survivor区。


年轻代空间的要点:
大多数新建的对象都位于Eden区。
当Eden区被对象填满时,就会执行Minor GC。并把所有存活下来的对象转移到其中一个survivor区。
Minor GC同样会检查存活下来的对象,并把它们转移到另一个survivor区。这样在一段时间内,总会有一个空的survivor区。
经过多次GC周期后,仍然存活下来的对象会被转移到年老代内存空间。通常这是在年轻代有资格提升到年老代前通过设定年龄阈值来完成的。

  • 年老代
年老代内存里包含了长期存活的对象和经过多次Minor GC后依然存活下来的对象。通常会在老年代内存被占满时进行垃圾回收。老年代的垃圾收集叫做Major GC。Major GC会花费更多的时间。


Stop the World事件
所有的垃圾收集都是“Stop the World”事件,因为所有的应用线程都会停下来直到操作完成(所以叫“Stop the World”)。

因为年轻代里的对象都是一些临时(short-lived )对象,执行Minor GC非常快,所以应用不会受到(“Stop the World”)影响。

由于Major GC会检查所有存活的对象,因此会花费更长的时间。应该尽量减少Major GC。因为Major GC会在垃圾回收期间让你的应用反应迟钝,所以如果你有一个需要快速响应的应用发生多次Major GC,你会看到超时错误。

垃圾回收时间取决于垃圾回收策略。这就是为什么有必要去监控垃圾收集和对垃圾收集进行调优。从而避免要求快速响应的应用出现超时错误。


  • 永久代
永久代或者“Perm Gen”包含了JVM需要的应用元数据,这些元数据描述了在应用里使用的类和方法。注意,永久代不是Java堆内存的一部分。
永久代存放JVM运行时使用的类。永久代同样包含了Java SE库的类和方法。永久代的对象在full GC时进行垃圾收集。


方法区
方法区是永久代空间的一部分,并用来存储类型信息(运行时常量和静态变量)和方法代码和构造函数代码。


内存池
如果JVM实现支持,JVM内存管理会为创建内存池,用来为不变对象创建对象池。字符串池就是内存池类型的一个很好的例子。内存池可以属于堆或者永久代,这取决于JVM内存管理的实现。


运行时常量池
运行时常量池是每个类常量池的运行时代表。它包含了类的运行时常量和静态方法。运行时常量池是方法区的一部分。


Java栈内存
Java栈内存用于运行线程。它们包含了方法里的临时数据、堆里其它对象引用的特定数据。

Java垃圾回收
Java垃圾回收会找出没用的对象,把它从内存中移除并释放出内存给以后创建的对象使用。Java程序语言中的一个最大优点是自动垃圾回收,不像其他的程序语言那样需要手动分配和释放内存,比如C语言。

垃圾收集器是一个后台运行程序。它管理着内存中的所有对象并找出没被引用的对象。所有的这些未引用的对象都会被删除,回收它们的空间并分配给其他对象。

一个基本的垃圾回收过程涉及三个步骤:
标记:这是第一步。在这一步,垃圾收集器会找出哪些对象正在使用和哪些对象不在使用。
正常清除:垃圾收集器清会除不在使用的对象,回收它们的空间分配给其他对象。
压缩清除:为了提升性能,压缩清除会在删除没用的对象后,把所有存活的对象移到一起。这样可以提高分配新对象的效率。


简单标记和清除方法存在两个问题:
效率很低。因为大多数新建对象都会成为“没用对象”。
经过多次垃圾回收周期的对象很有可能在以后的周期也会存活下来。
上面简单清除方法的问题在于Java垃圾收集的分代回收的,而且在堆内存里有年轻代和年老代两个区域。


  • Java垃圾回收类型
这里有五种可以在应用里使用的垃圾回收类型。

仅需要使用JVM开关就可以在我们的应用里启用垃圾回收策略。

Serial GC(-XX:+UseSerialGC):Serial GC使用简单的标记、清除、压缩方法对年轻代和年老代进行垃圾回收,即Minor GC和Major GC。Serial GC在client模式(客户端模式)很有用,比如在简单的独立应用和CPU配置较低的机器。这个模式对占有内存较少的应用很管用。
Parallel GC(-XX:+UseParallelGC):除了会产生N个线程来进行年轻代的垃圾收集外,Parallel GC和Serial GC几乎一样。这里的N是系统CPU的核数。我们可以使用 -XX:ParallelGCThreads=n 这个JVM选项来控制线程数量。并行垃圾收集器也叫throughput收集器。因为它使用了多CPU加快垃圾回收性能。Parallel GC在进行年老代垃圾收集时使用单线程。
Parallel Old GC(-XX:+UseParallelOldGC):和Parallel GC一样。不同之处,Parallel Old GC在年轻代垃圾收集和年老代垃圾回收时都使用多线程收集。
并发标记清除(CMS)收集器(-XX:+UseConcMarkSweepGC):CMS收集器也被称为短暂停顿并发收集器。它是对年老代进行垃圾收集的。CMS收集器通过多线程并发进行垃圾回收,尽量减少垃圾收集造成的停顿。CMS收集器对年轻代进行垃圾回收使用的算法和Parallel收集器一样。这个垃圾收集器适用于不能忍受长时间停顿要求快速响应的应用。可使用 -XX:ParallelCMSThreads=n JVM选项来限制CMS收集器的线程数量。
G1垃圾收集器(-XX:+UseG1GC) G1(Garbage First):垃圾收集器是在Java 7后才可以使用的特性,它的长远目标时代替CMS收集器。G1收集器是一个并行的、并发的和增量式压缩短暂停顿的垃圾收集器。G1收集器和其他的收集器运行方式不一样,不区分年轻代和年老代空间。它把堆空间划分为多个大小相等的区域。当进行垃圾收集时,它会优先收集存活对象较少的区域,因此叫“Garbage First”。

posted @ 2015-07-19 22:57 云云 阅读(1187) | 评论 (0)编辑 收藏

posted @ 2014-09-28 23:45 云云| 编辑 收藏

     摘要: class文件简介及加载     Java编译器编译好Java文件之后,产生.class 文件在磁盘中。这种class文件是二进制文件,内容是只有JVM虚拟机能够识别的机器码。JVM虚拟机读取字节码文件,取出二进制数据,加载到内存中,解析.class 文件内的信息,生成对应的 Class对象:     &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 云云 阅读(704) | 评论 (0)编辑 收藏

提升tomcat 性能 apr扩展lib
使用apr类库 可以让tomcat的性能提升到3到4倍  
目前项目中都使用这样的配置
<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 云云 阅读(890) | 评论 (0)编辑 收藏

     摘要: public static boolean acquireLock(String lock) {    // 1. 通过SETNX试图获取一个lock    boolean success = false;    Jedis jedis = pool.getResource();...  阅读全文

posted @ 2014-01-15 19:00 云云 阅读(13379) | 评论 (1)编辑 收藏

对eclipse的默认配置很不爽,黑色字体白色底好刺眼,而且字体习惯用Courier New
改变背景颜色:
windows->Preferences->General->Editor->Text Editors
右边选择Appearance color options 
选Background color 选择背景颜色
个人比较舒服的豆沙绿色和黑色背景,但黑色背景还要把其他的字体颜色也改了才好看,而且豆沙绿色跟默认的字体颜色搭配的很好。
豆沙绿色(色调:85   饱和度:123   亮度:205 )
据说这个色调是眼科专家配的, 因其颜色比较柔和,据说阅读的时候用这种颜色做背景有利于保护眼睛, word底色就许多人设置成豆沙绿色。
xml的字体调整: 
window--preferences--General--appearance--colors and fonts--Basic-- "Text font "  
然后点change,可以设置字体,我喜欢Courier New
Java的字体调整: 
window--preferences--General--appearance--colors and fonts--java 

posted @ 2014-01-09 16:41 云云 阅读(1792) | 评论 (0)编辑 收藏

有时候在项目中 会变化路径 把原有路径的文件拷到新的路径下面
再删除原来不想的路径再提交一次 这样以来 原来的路径确实不存在了
但是拷过来的文件带有原来路径的svn信息 这样以来 在提交的时候 就无法提交
想要文件按照的路径提交 但始终svn还是再往以前的路径提交 并提示你路径不存在
在网上搜了下 如何删除文件自带的svn路径信息
按照下面的方式来操作即可

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\" \""


把上面这段文字保存问一个Done.reg文件
然后执行,导入到注册表
就会在你右键一个文件夹的时候多出来一个菜单"删除该目录下面.svn文件"
执行该命令即可

 

posted @ 2013-12-05 17:17 云云 阅读(701) | 评论 (0)编辑 收藏

在ibatis中不需要关注这些参数 而转到mybatis后 如果字段值为空 必须设置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>

这些设置之多,太烦了,最让人烦的是  jdbcType = DATE,类型还必须大写,不能小写。
如下面的例子,将DATE 改成 Date 。结果让人很抓狂啊!!!
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时的时候用#{endTime,jdbcType=DATE},可以将时间插入成功,且可以精确到时分秒
但如果在update语句中也这样使用,那你得到的只会有日期,这够坑爹的了吧 ,尼玛  比起ibatis方便之处差远了
要想在update语句中 将时间格式化成时分秒 不得不再加一个类型 如下面:
startTime = #{startTime,javaType=DATE, jdbcType=VARCHAR}













posted @ 2013-11-26 21:02 云云 阅读(21404) | 评论 (1)编辑 收藏