jdk1.6 中使用 jconsole 需要包含的启动参数
-Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
注:
1. 远程连接才需要包含此参数(包括本地 web 应用),本地连接则不需要
2. 本地应用还要加参数 -jar,比如: -jar JDK_HOME/demo/jfc/Java2D/Java2Demo.jar
2008年12月30日星期二
jdk1.6 中使用 jconsole
jdk1.6 中使用 jconsole 需要包含的启动参数
-Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
注:远程连接才需要包含此参数(包括本地 web 应用),本地连接则不需要
-Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
注:远程连接才需要包含此参数(包括本地 web 应用),本地连接则不需要
2008年12月16日星期二
tomcat 缓存设置 filter
public class CacheFilter implements Filter {
private FilterConfig filterConfig;
public void doFilter( ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
String requestURI = httpRequest.getRequestURI();
if( !requestURI.contains(".nocache.") ){
long today = new Date().getTime();
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.setDateHeader("Expires", today+31536000000L);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
}
-----------------
web.xml 配置
-----------------
< filter>
< filter-name >CacheFilter< /filter-name >
< filter-class >com.rdews.cms.filters.CacheFilter< /filter-class >
< /filter >
< filter-mapping >
CacheFilter< /filter-name >
/gwt/*< /url-pattern >
< /filter-mapping >
private FilterConfig filterConfig;
public void doFilter( ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
String requestURI = httpRequest.getRequestURI();
if( !requestURI.contains(".nocache.") ){
long today = new Date().getTime();
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.setDateHeader("Expires", today+31536000000L);
}
filterChain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
this.filterConfig = null;
}
}
-----------------
web.xml 配置
-----------------
< filter>
< filter-name >CacheFilter< /filter-name >
< filter-class >com.rdews.cms.filters.CacheFilter< /filter-class >
< /filter >
< filter-mapping >
< /filter-mapping >
2008年11月28日星期五
JavaBean 之属性名称
问题:
在前端获取事件属性时,报错,找不到属性
目前的事件 SIMEventObject 中有这样的属性, sAddr,dAddr,它们的特的是第一个字母小写,第二个字母大写
但是在前端通过 ${event.sAddr}取值的时候,总是报找不到 sAddr 属性
这个问题以前也碰到过,但是没有往心里去,现在再次碰到,找了一下Java源码,才发现Java文档里其实有说明
原因:
1. 以前一直认为一个JavaBean,应该包括属性,setter,getter 方法,setter/getter 的命名规则则是将属性的第一个字母大写,前面加上 get/set ,但事实上不是这样,属性的名称跟 setter/getter 方法的名称无关,比如说,你可以这样写:
public class Bean{
private String anyword;
public void setProp(String anyword)
{ }
this.anyword = anyword;
}
public String getProp()
return anyword;
}
}
2. 对于 jstl 中的表达式 ${event.sAddr},实际的执行过程是这样:
a. 首选根据 event 的类型, 比如 SIMEventObject,得到其 BeanInfo
b. 在 BeanInfo 中 包含 event 的属性
c. 这个属性名称的来源是不是我们通常理解的 field, 而是根据 Bean 规范得到的(应该是根据 setter/getter 方法)
d. 得到属性名称时,它会将得到的属性字串的第一个字母去大写化,比如 由getDevAddr,得到 DevAddr,然后最后得到的是 devAddr;
e. 但是如果属性有多个字母,且第一个字母,第二个字母都大写的,则不做处理,比如 getSAddr,则直接返回 SAddr,也就是说,它认为 SAddr 是这个 Bean 的属性,而不是 sAddr
下面是部分过程代码:
BeanInfo mBeanInfo = Introspector.getBeanInfo (SIMEventObject.class);
PropertyDescriptor[] pds = mBeanInfo.getPropertyDescriptors();
Map propMap = new TreeMap();
Method readMethod = getPublicMethod (pd.getReadMethod ());
Method writeMethod = getPublicMethod (pd.getWriteMethod ());
BeanInfoProperty property = new BeanInfoProperty(readMethod,writeMethod,pd);
for(PropertyDescriptor pd : pds)
{
//问题在这里,就是 pd.getName(),对于第一个字母,第二个字母都是大写的,它不会做处理,即,SAddr/Saddr/SaDrr/saddr,返回 SAddr/saddr/saDrr/saddr 但对于其他情况,则将第一个字母变成小写返回,比如 saddr/SaDdr,则返回 saddr;但是当取值${event.sAddr}时,它会从 map 中获取属性,用如下方法: propMap.get("sAddr"),而实际上 propMap 中的key值是 SAddr,所以,如果我们将表达式换成 ${event.SAddr}
即可
propMap.put(pd.getName(),pd)
}
----------------------------------
将首字母变成小写调用是以下方法:
java.beans.Introspector
decapitalize
public static String decapitalize(String name)获得一个字符串并将它转换成普通 Java 可用名称大写形式的实用程序方法。这通常意味着将首字符从大写转换成小写,但在(不平常的)特殊情况下,当有多个字符且第一个和第二个字符都是大写字符时,不执行任何操作。
因此 "FooBah" 变成 "fooBah","X" 变成 "x",但 "URL" 仍然是 "URL"。
在前端获取事件属性时,报错,找不到属性
目前的事件 SIMEventObject 中有这样的属性, sAddr,dAddr,它们的特的是第一个字母小写,第二个字母大写
但是在前端通过 ${event.sAddr}取值的时候,总是报找不到 sAddr 属性
这个问题以前也碰到过,但是没有往心里去,现在再次碰到,找了一下Java源码,才发现Java文档里其实有说明
原因:
1. 以前一直认为一个JavaBean,应该包括属性,setter,getter 方法,setter/getter 的命名规则则是将属性的第一个字母大写,前面加上 get/set ,但事实上不是这样,属性的名称跟 setter/getter 方法的名称无关,比如说,你可以这样写:
public class Bean{
private String anyword;
public void setProp(String anyword)
{ }
this.anyword = anyword;
}
public String getProp()
return anyword;
}
}
2. 对于 jstl 中的表达式 ${event.sAddr},实际的执行过程是这样:
a. 首选根据 event 的类型, 比如 SIMEventObject,得到其 BeanInfo
b. 在 BeanInfo 中 包含 event 的属性
c. 这个属性名称的来源是不是我们通常理解的 field, 而是根据 Bean 规范得到的(应该是根据 setter/getter 方法)
d. 得到属性名称时,它会将得到的属性字串的第一个字母去大写化,比如 由getDevAddr,得到 DevAddr,然后最后得到的是 devAddr;
e. 但是如果属性有多个字母,且第一个字母,第二个字母都大写的,则不做处理,比如 getSAddr,则直接返回 SAddr,也就是说,它认为 SAddr 是这个 Bean 的属性,而不是 sAddr
下面是部分过程代码:
BeanInfo mBeanInfo = Introspector.getBeanInfo (SIMEventObject.class);
PropertyDescriptor[] pds = mBeanInfo.getPropertyDescriptors();
Map propMap = new TreeMap();
Method readMethod = getPublicMethod (pd.getReadMethod ());
Method writeMethod = getPublicMethod (pd.getWriteMethod ());
BeanInfoProperty property = new BeanInfoProperty(readMethod,writeMethod,pd);
for(PropertyDescriptor pd : pds)
{
//问题在这里,就是 pd.getName(),对于第一个字母,第二个字母都是大写的,它不会做处理,即,SAddr/Saddr/SaDrr/saddr,返回 SAddr/saddr/saDrr/saddr 但对于其他情况,则将第一个字母变成小写返回,比如 saddr/SaDdr,则返回 saddr;但是当取值${event.sAddr}时,它会从 map 中获取属性,用如下方法: propMap.get("sAddr"),而实际上 propMap 中的key值是 SAddr,所以,如果我们将表达式换成 ${event.SAddr}
即可
propMap.put(pd.getName(),pd)
}
----------------------------------
将首字母变成小写调用是以下方法:
java.beans.Introspector
decapitalize
public static String decapitalize(String name)获得一个字符串并将它转换成普通 Java 可用名称大写形式的实用程序方法。这通常意味着将首字符从大写转换成小写,但在(不平常的)特殊情况下,当有多个字符且第一个和第二个字符都是大写字符时,不执行任何操作。
因此 "FooBah" 变成 "fooBah","X" 变成 "x",但 "URL" 仍然是 "URL"。
2008年11月25日星期二
Yahoo!网站性能最佳体验的34条黄金守则之JavaScript和CSS
Yahoo!网站性能最佳体验的34条黄金守则之JavaScript和CSS
From: http://hi.baidu.com/szhesh/blog/item/25276d344d57ac3d5bb5f585.html
在第一部分和第二部分中我们分别介绍了改善网站性能中页面内容和服务器的几条守则,除此之外,JavaScript和CSS也是我们页面中经常用到的内容,对它们的优化也提高网站性能的重要方面:
CSS:
把样式表置于顶部
避免使用CSS表达式(Expression)
使用外部JavaScript和CSS
削减JavaScript和CSS
用< link>代替@import
避免使用滤镜
JavaScript
把脚本置于页面底部
使用外部JavaScript和CSS
削减JavaScript和CSS
剔除重复脚本
减少DOM访问
开发智能事件处理程序
17、把样式表置于顶部
在研究Yahoo!的性能表现时,我们发现把样式表放到文档的< head />内部似乎会加快页面的下载速度。这是因为把样式表放到< head />内会使页面有步骤的加载显示。
注重性能的前端服务器往往希望页面有秩序地加载。同时,我们也希望浏览器把已经接收到内容尽可能显示出来。这对于拥有较多内容的页面和网速较慢的用户来说特别重要。向用户返回可视化的反馈,比如进程指针,已经有了较好的研究并形成了正式文档。在我们的研究中HTML页面就是进程指针。当浏览器有序地加载文件头、导航栏、顶部的logo等对于等待页面加载的用户来说都可以作为可视化的反馈。这从整体上改善了用户体验。
把样式表放在文档底部的问题是在包括Internet Explorer在内的很多浏览器中这会中止内容的有序呈现。浏览器中止呈现是为了避免样式改变引起的页面元素重绘。用户不得不面对一个空白页面。
HTML规范清楚指出样式表要放包含在页面的< head />区域内:“和< a />不同,< link />只能出现在文档的< head />区域内,尽管它可以多次使用它”。无论是引起白屏还是出现没有样式化的内容都不值得去尝试。最好的方案就是按照HTML规范在文档< head />内加载你的样式表。
18、避免使用CSS表达式(Expression)
CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景颜色:
background-color: expression( (new Date()).getHours()%2 "#B8D4FF" : "#F08A00" );
如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。expression方法在其它浏览器中不起作用,因此在跨浏览器的设计中单独针对Internet Explorer设置时会比较有用。
表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。
一个减少CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。如果样式属性必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。如果必须使用CSS表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。
19、使用外部JavaScript和CSS
很多性能规则都是关于如何处理外部文件的。但是,在你采取这些措施前你可能会问到一个更基本的问题:JavaScript和CSS是应该放在外部文件中呢还是把它们放在页面本身之内呢?
在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏览器中产生缓存。内置在HTML文档中的JavaScript 和CSS则会在每次请求中随HTML文档重新下载。这虽然减少了HTTP请求的次数,却增加了HTML文档的大小。从另一方面来说,如果外部文件中的 JavaScript和CSS被浏览器缓存,在没有增加HTTP请求次数的同时可以减少HTML文档的大小。
关键问题是,外部JavaScript和CSS文件缓存的频率和请求HTML文档的次数有关。虽然有一定的难度,但是仍然有一些指标可以一测量它。如果一个会话中用户会浏览你网站中的多个页面,并且这些页面中会重复使用相同的脚本和样式表,缓存外部文件就会带来更大的益处。
许多网站没有功能建立这些指标。对于这些网站来说,最好的坚决方法就是把JavaScript和CSS作为外部文件引用。比较适合使用内置代码的例外就是网站的主页,如Yahoo!主页和My Yahoo!。主页在一次会话中拥有较少(可能只有一次)的浏览量,你可以发现内置JavaScript和CSS对于终端用户来说会加快响应时 间。
对于拥有较大浏览量的首页来说,有一种技术可以平衡内置代码带来的HTTP请求减少与通过使用外部文件进行缓存带来的好处。其中一个就是在首页中内置 JavaScript和CSS,但是在页面下载完成后动态下载外部文件,在子页面中使用到这些文件时,它们已经缓存到浏览器了。
20、削减JavaScript和CSS
精简是指从去除代码不必要的字符减少文件大小从而节省下载时间。消减代码时,所有的注释、不需要的空白字符(空格、换行、tab缩进)等都要去掉。在 JavaScript中,由于需要下载的文件体积变小了从而节省了响应时间。精简JavaScript中目前用到的最广泛的两个工具是JSMin和YUI Compressor。YUI Compressor还可用于精简CSS。
混淆是另外一种可用于源代码优化的方法。这种方法要比精简复杂一些并且在混淆的过程更易产生问题。在对美国前10大网站的调查中发现,精简也可以缩小原来代码体积的21%,而混淆可以达到25%。尽管混淆法可以更好地缩减代码,但是对于JavaScript来说精简的风险更小。
除消减外部的脚本和样式表文件外,< script>和< style>代码块也可以并且应该进行消减。即使你用Gzip压缩过脚本和样式表,精简这些文件仍然可以节省5%以上的空间。由于JavaScript和CSS的功能和体积的增加,消减代码将会获得益处。
21、用< link>代替@import
前面的最佳实现中提到CSS应该放置在顶端以利于有序加载呈现。
在IE中,页面底部@import和使用< link>作用是一样的,因此最好不要使用它。
22、避免使用滤镜
IE独有属性AlphaImageLoader用于修正7.0以下版本中显示PNG图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现并且冻结浏览器。在每一个元素(不仅仅是图片)它都会运算一次,增加了内存开支,因此它的问题是多方面的。
完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工作。如果你确实需要使用AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。
23、把脚本置于页面底部
脚本带来的问题就是它阻止了页面的平行下载。HTTP/1.1 规范建议,浏览器每个主机名的并行下载内容不超过两个。如果你的图片放在多个主机名上,你可以在每个并行下载中同时下载2个以上的文件。但是当下载脚本时,浏览器就不会同时下载其它文件了,即便是主机名不相同。
在某些情况下把脚本移到页面底部可能不太容易。比如说,如果脚本中使用了document.write来插入页面内容,它就不能被往下移动了。这里可能还会有作用域的问题。很多情况下,都会遇到这方面的问题。
一个经常用到的替代方法就是使用延迟脚本。DEFER属性表明脚本中没有包含document.write,它告诉浏览器继续显示。不幸的是,Firefox并不支持DEFER属性。在Internet Explorer中,脚本可能会被延迟但效果也不会像我们所期望的那样。如果脚本可以被延迟,那么它就可以移到页面的底部。这会让你的页面加载的快一点。
24、剔除重复脚本
在同一个页面中重复引用JavaScript文件会影响页面的性能。你可能会认为这种情况并不多见。对于美国前10大网站的调查显示其中有两家存在重复引用脚本的情况。有两种主要因素导致一个脚本被重复引用的奇怪现象发生:团队规模和脚本数量。如果真的存在这种情况,重复脚本会引起不必要的HTTP请求和无用的JavaScript运算,这降低了网站性能。
在Internet Explorer中会产生不必要的HTTP请求,而在Firefox却不会。在Internet Explorer中,如果一个脚本被引用两次而且它又不可缓存,它就会在页面加载过程中产生两次HTTP请求。即时脚本可以缓存,当用户重载页面时也会产生额外的HTTP请求。
除增加额外的HTTP请求外,多次运算脚本也会浪费时间。在Internet Explorer和Firefox中不管脚本是否可缓存,它们都存在重复运算JavaScript的问题。
一个避免偶尔发生的两次引用同一脚本的方法是在模板中使用脚本管理模块引用脚本。在HTML页面中使用< script />标签引用脚本的最常见方法就是:
< script type="text/javascript" src="menu_1.0.17.js">< /script>
在PHP中可以通过创建名为insertScript的方法来替代:
< php insertScript("menu.js") >
为了防止多次重复引用脚本,这个方法中还应该使用其它机制来处理脚本,如检查所属目录和为脚本文件名中增加版本号以用于Expire文件头等。
25、减少DOM访问
使用JavaScript访问DOM元素比较慢,因此为了获得更多的应该页面,应该做到:
缓存已经访问过的有关元素
线下更新完节点之后再将它们添加到文档树中
避免使用JavaScript来修改页面布局
有关此方面的更多信息请查看Julien Lecomte在YUI专题中的文章“高性能Ajax应该程序”。
26、开发智能事件处理程序
有时候我们会感觉到页面反应迟钝,这是因为DOM树元素中附加了过多的事件句柄并且些事件句病被频繁地触发。这就是为什么说使用event delegation(事件代理)是一种好方法了。如果你在一个div中有10个按钮,你只需要在div上附加一次事件句柄就可以了,而不用去为每一个按钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是哪个事件发出的。
你同样也不用为了操作DOM树而等待onload事件的发生。你需要做的就是等待树结构中你要访问的元素出现。你也不用等待所有图像都加载完毕。
你可能会希望用DOMContentLoaded事件来代替onload,但是在所有浏览器都支持它之前你可使用YUI 事件应用程序中的onAvailable方法。
有关此方面的更多信息请查看Julien Lecomte在YUI专题中的文章“高性能Ajax应该程序”。
From: http://hi.baidu.com/szhesh/blog/item/25276d344d57ac3d5bb5f585.html
在第一部分和第二部分中我们分别介绍了改善网站性能中页面内容和服务器的几条守则,除此之外,JavaScript和CSS也是我们页面中经常用到的内容,对它们的优化也提高网站性能的重要方面:
CSS:
把样式表置于顶部
避免使用CSS表达式(Expression)
使用外部JavaScript和CSS
削减JavaScript和CSS
用< link>代替@import
避免使用滤镜
JavaScript
把脚本置于页面底部
使用外部JavaScript和CSS
削减JavaScript和CSS
剔除重复脚本
减少DOM访问
开发智能事件处理程序
17、把样式表置于顶部
在研究Yahoo!的性能表现时,我们发现把样式表放到文档的< head />内部似乎会加快页面的下载速度。这是因为把样式表放到< head />内会使页面有步骤的加载显示。
注重性能的前端服务器往往希望页面有秩序地加载。同时,我们也希望浏览器把已经接收到内容尽可能显示出来。这对于拥有较多内容的页面和网速较慢的用户来说特别重要。向用户返回可视化的反馈,比如进程指针,已经有了较好的研究并形成了正式文档。在我们的研究中HTML页面就是进程指针。当浏览器有序地加载文件头、导航栏、顶部的logo等对于等待页面加载的用户来说都可以作为可视化的反馈。这从整体上改善了用户体验。
把样式表放在文档底部的问题是在包括Internet Explorer在内的很多浏览器中这会中止内容的有序呈现。浏览器中止呈现是为了避免样式改变引起的页面元素重绘。用户不得不面对一个空白页面。
HTML规范清楚指出样式表要放包含在页面的< head />区域内:“和< a />不同,< link />只能出现在文档的< head />区域内,尽管它可以多次使用它”。无论是引起白屏还是出现没有样式化的内容都不值得去尝试。最好的方案就是按照HTML规范在文档< head />内加载你的样式表。
18、避免使用CSS表达式(Expression)
CSS表达式是动态设置CSS属性的强大(但危险)方法。Internet Explorer从第5个版本开始支持CSS表达式。下面的例子中,使用CSS表达式可以实现隔一个小时切换一次背景颜色:
background-color: expression( (new Date()).getHours()%2 "#B8D4FF" : "#F08A00" );
如上所示,expression中使用了JavaScript表达式。CSS属性根据JavaScript表达式的计算结果来设置。expression方法在其它浏览器中不起作用,因此在跨浏览器的设计中单独针对Internet Explorer设置时会比较有用。
表达式的问题就在于它的计算频率要比我们想象的多。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次。给CSS表达式增加一个计数器可以跟踪表达式的计算频率。在页面中随便移动鼠标都可以轻松达到10000次以上的计算量。
一个减少CSS表达式计算次数的方法就是使用一次性的表达式,它在第一次运行时将结果赋给指定的样式属性,并用这个属性来代替CSS表达式。如果样式属性必须在页面周期内动态地改变,使用事件句柄来代替CSS表达式是一个可行办法。如果必须使用CSS表达式,一定要记住它们要计算成千上万次并且可能会对你页面的性能产生影响。
19、使用外部JavaScript和CSS
很多性能规则都是关于如何处理外部文件的。但是,在你采取这些措施前你可能会问到一个更基本的问题:JavaScript和CSS是应该放在外部文件中呢还是把它们放在页面本身之内呢?
在实际应用中使用外部文件可以提高页面速度,因为JavaScript和CSS文件都能在浏览器中产生缓存。内置在HTML文档中的JavaScript 和CSS则会在每次请求中随HTML文档重新下载。这虽然减少了HTTP请求的次数,却增加了HTML文档的大小。从另一方面来说,如果外部文件中的 JavaScript和CSS被浏览器缓存,在没有增加HTTP请求次数的同时可以减少HTML文档的大小。
关键问题是,外部JavaScript和CSS文件缓存的频率和请求HTML文档的次数有关。虽然有一定的难度,但是仍然有一些指标可以一测量它。如果一个会话中用户会浏览你网站中的多个页面,并且这些页面中会重复使用相同的脚本和样式表,缓存外部文件就会带来更大的益处。
许多网站没有功能建立这些指标。对于这些网站来说,最好的坚决方法就是把JavaScript和CSS作为外部文件引用。比较适合使用内置代码的例外就是网站的主页,如Yahoo!主页和My Yahoo!。主页在一次会话中拥有较少(可能只有一次)的浏览量,你可以发现内置JavaScript和CSS对于终端用户来说会加快响应时 间。
对于拥有较大浏览量的首页来说,有一种技术可以平衡内置代码带来的HTTP请求减少与通过使用外部文件进行缓存带来的好处。其中一个就是在首页中内置 JavaScript和CSS,但是在页面下载完成后动态下载外部文件,在子页面中使用到这些文件时,它们已经缓存到浏览器了。
20、削减JavaScript和CSS
精简是指从去除代码不必要的字符减少文件大小从而节省下载时间。消减代码时,所有的注释、不需要的空白字符(空格、换行、tab缩进)等都要去掉。在 JavaScript中,由于需要下载的文件体积变小了从而节省了响应时间。精简JavaScript中目前用到的最广泛的两个工具是JSMin和YUI Compressor。YUI Compressor还可用于精简CSS。
混淆是另外一种可用于源代码优化的方法。这种方法要比精简复杂一些并且在混淆的过程更易产生问题。在对美国前10大网站的调查中发现,精简也可以缩小原来代码体积的21%,而混淆可以达到25%。尽管混淆法可以更好地缩减代码,但是对于JavaScript来说精简的风险更小。
除消减外部的脚本和样式表文件外,< script>和< style>代码块也可以并且应该进行消减。即使你用Gzip压缩过脚本和样式表,精简这些文件仍然可以节省5%以上的空间。由于JavaScript和CSS的功能和体积的增加,消减代码将会获得益处。
21、用< link>代替@import
前面的最佳实现中提到CSS应该放置在顶端以利于有序加载呈现。
在IE中,页面底部@import和使用< link>作用是一样的,因此最好不要使用它。
22、避免使用滤镜
IE独有属性AlphaImageLoader用于修正7.0以下版本中显示PNG图片的半透明效果。这个滤镜的问题在于浏览器加载图片时它会终止内容的呈现并且冻结浏览器。在每一个元素(不仅仅是图片)它都会运算一次,增加了内存开支,因此它的问题是多方面的。
完全避免使用AlphaImageLoader的最好方法就是使用PNG8格式来代替,这种格式能在IE中很好地工作。如果你确实需要使用AlphaImageLoader,请使用下划线_filter又使之对IE7以上版本的用户无效。
23、把脚本置于页面底部
脚本带来的问题就是它阻止了页面的平行下载。HTTP/1.1 规范建议,浏览器每个主机名的并行下载内容不超过两个。如果你的图片放在多个主机名上,你可以在每个并行下载中同时下载2个以上的文件。但是当下载脚本时,浏览器就不会同时下载其它文件了,即便是主机名不相同。
在某些情况下把脚本移到页面底部可能不太容易。比如说,如果脚本中使用了document.write来插入页面内容,它就不能被往下移动了。这里可能还会有作用域的问题。很多情况下,都会遇到这方面的问题。
一个经常用到的替代方法就是使用延迟脚本。DEFER属性表明脚本中没有包含document.write,它告诉浏览器继续显示。不幸的是,Firefox并不支持DEFER属性。在Internet Explorer中,脚本可能会被延迟但效果也不会像我们所期望的那样。如果脚本可以被延迟,那么它就可以移到页面的底部。这会让你的页面加载的快一点。
24、剔除重复脚本
在同一个页面中重复引用JavaScript文件会影响页面的性能。你可能会认为这种情况并不多见。对于美国前10大网站的调查显示其中有两家存在重复引用脚本的情况。有两种主要因素导致一个脚本被重复引用的奇怪现象发生:团队规模和脚本数量。如果真的存在这种情况,重复脚本会引起不必要的HTTP请求和无用的JavaScript运算,这降低了网站性能。
在Internet Explorer中会产生不必要的HTTP请求,而在Firefox却不会。在Internet Explorer中,如果一个脚本被引用两次而且它又不可缓存,它就会在页面加载过程中产生两次HTTP请求。即时脚本可以缓存,当用户重载页面时也会产生额外的HTTP请求。
除增加额外的HTTP请求外,多次运算脚本也会浪费时间。在Internet Explorer和Firefox中不管脚本是否可缓存,它们都存在重复运算JavaScript的问题。
一个避免偶尔发生的两次引用同一脚本的方法是在模板中使用脚本管理模块引用脚本。在HTML页面中使用< script />标签引用脚本的最常见方法就是:
< script type="text/javascript" src="menu_1.0.17.js">< /script>
在PHP中可以通过创建名为insertScript的方法来替代:
< php insertScript("menu.js") >
为了防止多次重复引用脚本,这个方法中还应该使用其它机制来处理脚本,如检查所属目录和为脚本文件名中增加版本号以用于Expire文件头等。
25、减少DOM访问
使用JavaScript访问DOM元素比较慢,因此为了获得更多的应该页面,应该做到:
缓存已经访问过的有关元素
线下更新完节点之后再将它们添加到文档树中
避免使用JavaScript来修改页面布局
有关此方面的更多信息请查看Julien Lecomte在YUI专题中的文章“高性能Ajax应该程序”。
26、开发智能事件处理程序
有时候我们会感觉到页面反应迟钝,这是因为DOM树元素中附加了过多的事件句柄并且些事件句病被频繁地触发。这就是为什么说使用event delegation(事件代理)是一种好方法了。如果你在一个div中有10个按钮,你只需要在div上附加一次事件句柄就可以了,而不用去为每一个按钮增加一个句柄。事件冒泡时你可以捕捉到事件并判断出是哪个事件发出的。
你同样也不用为了操作DOM树而等待onload事件的发生。你需要做的就是等待树结构中你要访问的元素出现。你也不用等待所有图像都加载完毕。
你可能会希望用DOMContentLoaded事件来代替onload,但是在所有浏览器都支持它之前你可使用YUI 事件应用程序中的onAvailable方法。
有关此方面的更多信息请查看Julien Lecomte在YUI专题中的文章“高性能Ajax应该程序”。
2008年11月18日星期二
50个最好且免费的 ajax 例子
作者: ╱/罒呍唲 链接:http://www.javaeye.com/news/4050-50-free-and-the-best-example-of-ajax 发表时间: 2008年11月05日
声明:本文系JavaEye网站发布的原创新闻,严禁任何网站转载本文,否则必将追究法律责任!
Web应用程序已经取得了跨越式的发展,我们要感谢下Ajax 技术。
以下是我们提供的最好的而且免费提供的脚本,这些例子中使用了jQuery, Mootools, Prototype 和script.aculo.us ,不妨尝试一下!
Ajax Forms
ShoutBox
Validate a Username AJAX
Ajax Instant Messenger
Ajax Tabs Content
Ajax Shopping Carts
Ajax Star Ratings
Ajax Inline Edit
Ajax Progress Bar
Ajax Pagination
Ajax File Browser & Manager
Ajax Calendar
Ajax Photo Manipulation
Ajax Dynamic Image Gallery and Slideshows
Ajax File Upload
Ajax AutoCompleter
CMS
Polls
Tabular data manipulations
Miscellaneous
- Ajax Scrolling pages
- jTip – A jQuery Tool Tip
- Ajax Broken Link Checker
- Facebox
- Drop Down Panel script
来自:noupe.com
已有 8 人发表留言,猛击->>这里<<-参与讨论
JavaEye推荐
windows 下删除 .svn 文件
From: http://www.google.com/reader/view/feed/http%3A%2F%2Ffeed.awflasher.com%2F?hl=en
SVN是我认为目前最方便的版本管理体系。我最早一次接触版本管理是2004年,当时学校BBS的代码要求用CVS管理;第二次亲密接触是在2006年,当时公司的代码使用Eclipse+CVS管理;而第一次使用SVN则是在2007年的一个封闭开发项目。
我十分喜欢SVN的方便,无论是在Linux下的命令行操作还是在Windows下的资源管理器插件,都十分简易。而且code.google.com也支持SVN来供我们发布、维护开源项目(例如我的WordPress主题TES)然而,久而久之,SVN文件夹下会有许多.svn的“meta数据”。这些数据久而久之会带来不少麻烦。尤其是基于资源管理器交互的Windows系统。
今天看了Jon Galloway的一个注册表脚本,十分方便,分享如下:
建立一个文本文件,取名为kill-svn-folders.reg(扩展名由txt改为reg),内容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"
[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\" \""
保存之后,双击这个reg文件。成功后,在每一个文件夹上点击右键都会有一个“Delete SVN Folders”的选项,点击之后,既可以删除这个文件下下面所有的.svn文件了:
SVN是我认为目前最方便的版本管理体系。我最早一次接触版本管理是2004年,当时学校BBS的代码要求用CVS管理;第二次亲密接触是在2006年,当时公司的代码使用Eclipse+CVS管理;而第一次使用SVN则是在2007年的一个封闭开发项目。
我十分喜欢SVN的方便,无论是在Linux下的命令行操作还是在Windows下的资源管理器插件,都十分简易。而且code.google.com也支持SVN来供我们发布、维护开源项目(例如我的WordPress主题TES)然而,久而久之,SVN文件夹下会有许多.svn的“meta数据”。这些数据久而久之会带来不少麻烦。尤其是基于资源管理器交互的Windows系统。
今天看了Jon Galloway的一个注册表脚本,十分方便,分享如下:
建立一个文本文件,取名为kill-svn-folders.reg(扩展名由txt改为reg),内容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"
[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\" \""
保存之后,双击这个reg文件。成功后,在每一个文件夹上点击右键都会有一个“Delete SVN Folders”的选项,点击之后,既可以删除这个文件下下面所有的.svn文件了:
2008年11月12日星期三
2008年11月11日星期二
windows 服务无法关闭的问题解决过程
问题:服务启动后,通过 windows 的服务管理程序停止服务时,报 "1053 错误,无法正常关闭服务",但实际上所有的应用,包括 mysql 都已经关掉。
解决步骤及思路:
1. 在系统信息里查看详细的报错信息,系统没有记录(可能是 windows 不记录其他应用服务的报错信息)
2. Google,查到 MSDN 文档,说的很清楚,就是调用关闭服务的时候超时(默认 30 秒),解决这个问题需要安装 .Net Framework 1.1 SP1
3. 由于我的机器本身安装了 .Net Framework 2.0 SP1,所以怀疑不是这个的原因,另外一个原因是懒的卸载 2.0再安装 1.1
4. 由于安装服务的命令是 windows 自带的 SC 命令,查找 SC 的用法,看是否有增加延时设置的地方,未果
5. 再 Google ,未找到合适的解决方案
6. 下载 .net 1.1 及 sp1,卸载本机 .net 2.0,安装 .net 1.1 sp1,重启机器,问题未解决
7. 想到可能是在关闭服务的时候,在等待其他应用返回或关闭,而造成超时。检查脚本及代码,发现关闭应用时,同时会关闭 数据库,试者手动关闭数据库,再关闭服务,成功。怀疑问题出在这里,但尚未确认。
8. 检查关闭数据库的代码,是在 tomcat 关闭时,在 Servlet 的 destroy 方法中关闭,代码如下:
public void destroy()
{
logger.info("SecFox server is stopping......");
try
{
ManageServer.getManageServer().shutdown();
}catch(Exception e)
{
logger.info("Stop SecFox server:",e);
}
try
{
String stopdb = serverpro.getProperty("stopdb");
if (!stopdb.equals(""))
{
Runtime.getRuntime().exec(stopdb,null,new File(rootDir));
logger.info("Stop database.");
}
}catch(Exception e)
{
logger.info("Stop database:",e);
}
logger.info("SecFox server has stop.");
System.exit(0);
}
9. 检查代码,怀疑是 最后一句 System.exit(0) 造成 jvm 强行退出,而关闭服务的进程还在等待返回,试着注释掉这句,重启应用,结果依旧;试着把 mysql 手动停掉,再关服务,可以正常关闭。多次起动/关闭服务,前两次可以正常关闭,以后又失败。
10. 想啊想,不得其解,觉得问题还是在这里,怀疑是缓存问题,第二天试着把 tomcat 缓存清掉,再试,成功
11. 换一台机器,在不改代码的情况下试,问题依旧;换代码,清缓存,再试,问题解决
12. 由于服务启动的过程中,需要调用脚本启动 mysql,服务启动后,mysql 要过一会儿才能启动,如果此时关闭服务,由于 mysql 还没有启动,所以仍然会报 1053 错误;测试:
a. 启动服务,马上关闭服务,报错落
b. 启动服务,等 mysql 起来后,再关闭服务,正常
--------------------------
附 Runtime.exit() 的JavaDoc :
通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭挂钩(如果有的话),并且允许它们同时运行直至结束。在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。
如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭挂钩,则将无限期地阻断此方法。如果已经运行完关闭挂钩,并且已启用退出终结 (on-exit finalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
解决步骤及思路:
1. 在系统信息里查看详细的报错信息,系统没有记录(可能是 windows 不记录其他应用服务的报错信息)
2. Google,查到 MSDN 文档,说的很清楚,就是调用关闭服务的时候超时(默认 30 秒),解决这个问题需要安装 .Net Framework 1.1 SP1
3. 由于我的机器本身安装了 .Net Framework 2.0 SP1,所以怀疑不是这个的原因,另外一个原因是懒的卸载 2.0再安装 1.1
4. 由于安装服务的命令是 windows 自带的 SC 命令,查找 SC 的用法,看是否有增加延时设置的地方,未果
5. 再 Google ,未找到合适的解决方案
6. 下载 .net 1.1 及 sp1,卸载本机 .net 2.0,安装 .net 1.1 sp1,重启机器,问题未解决
7. 想到可能是在关闭服务的时候,在等待其他应用返回或关闭,而造成超时。检查脚本及代码,发现关闭应用时,同时会关闭 数据库,试者手动关闭数据库,再关闭服务,成功。怀疑问题出在这里,但尚未确认。
8. 检查关闭数据库的代码,是在 tomcat 关闭时,在 Servlet 的 destroy 方法中关闭,代码如下:
public void destroy()
{
logger.info("SecFox server is stopping......");
try
{
ManageServer.getManageServer().shutdown();
}catch(Exception e)
{
logger.info("Stop SecFox server:",e);
}
try
{
String stopdb = serverpro.getProperty("stopdb");
if (!stopdb.equals(""))
{
Runtime.getRuntime().exec(stopdb,null,new File(rootDir));
logger.info("Stop database.");
}
}catch(Exception e)
{
logger.info("Stop database:",e);
}
logger.info("SecFox server has stop.");
System.exit(0);
}
9. 检查代码,怀疑是 最后一句 System.exit(0) 造成 jvm 强行退出,而关闭服务的进程还在等待返回,试着注释掉这句,重启应用,结果依旧;试着把 mysql 手动停掉,再关服务,可以正常关闭。多次起动/关闭服务,前两次可以正常关闭,以后又失败。
10. 想啊想,不得其解,觉得问题还是在这里,怀疑是缓存问题,第二天试着把 tomcat 缓存清掉,再试,成功
11. 换一台机器,在不改代码的情况下试,问题依旧;换代码,清缓存,再试,问题解决
12. 由于服务启动的过程中,需要调用脚本启动 mysql,服务启动后,mysql 要过一会儿才能启动,如果此时关闭服务,由于 mysql 还没有启动,所以仍然会报 1053 错误;测试:
a. 启动服务,马上关闭服务,报错落
b. 启动服务,等 mysql 起来后,再关闭服务,正常
--------------------------
附 Runtime.exit() 的JavaDoc :
通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭挂钩(如果有的话),并且允许它们同时运行直至结束。在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。
如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭挂钩,则将无限期地阻断此方法。如果已经运行完关闭挂钩,并且已启用退出终结 (on-exit finalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
2008年10月13日星期一
漏洞评估与攻击恢复
漏洞评估在安全生命周期里是一个关键过程。他们决定了系统的安全健康证书。他们应该被计划成为你的安全维护过程的一个规则部分,因为漏洞是持续被发现的。你能用同样的或者相似的工具来对付那些黑客,以确保你的站点面对外界攻击时是安全的。以下是我推荐的一些免费工具:
www.insecure.org/nmap的网络扫描器(Nmap)
www.nessus.org的Nessus
www.microsoft.com/technet/security/tools/mbsahome.mspx 的微软Security Baseline Ananlyzer
http://www.cert.org/tech_tips/root_compromise.html 提供了一份很好的讲述如何从Unix和Windows系统攻击中进行恢复的检查清单和步骤。
www.insecure.org/nmap的网络扫描器(Nmap)
www.nessus.org的Nessus
www.microsoft.com/technet/security/tools/mbsahome.mspx 的微软Security Baseline Ananlyzer
http://www.cert.org/tech_tips/root_compromise.html 提供了一份很好的讲述如何从Unix和Windows系统攻击中进行恢复的检查清单和步骤。
2008年9月25日星期四
xquery 简单使用
一、测试执行 xquery 的方法:
1. 用工具
比如 stylus studio (www.stylusstudio.com)
2. 利用 Saxon
命令行如下: java -cp saxon8.jar net.sf.saxon.Query test.xml
其中 test.xml 的内容可以如下:
doc('http://www.stylusstudio.com/examples/videos.xml')
//actors/actor[@id="00000030"]
二、xquery 的 FLWOR(pronounced flower) 表达式 for/let/where/order by/return
比如:
let $doc := doc('http://www.stylusstudio.com/examples/videos.xml')
for $v in $doc//video,$a in $doc//actors/actor
where ends-with($a, 'Lisa') and $v/actorRef = $a/@id
return $v/title
1. 用工具
比如 stylus studio (www.stylusstudio.com)
2. 利用 Saxon
命令行如下: java -cp saxon8.jar net.sf.saxon.Query test.xml
其中 test.xml 的内容可以如下:
doc('http://www.stylusstudio.com/examples/videos.xml')
//actors/actor[@id="00000030"]
二、xquery 的 FLWOR(pronounced flower) 表达式 for/let/where/order by/return
比如:
let $doc := doc('http://www.stylusstudio.com/examples/videos.xml')
for $v in $doc//video,$a in $doc//actors/actor
where ends-with($a, 'Lisa') and $v/actorRef = $a/@id
return $v/title
2008年9月12日星期五
OutOfMemoryError
一、内存溢出类型
1、java.lang.OutOfMemoryError: PermGen space
JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。
2、java.lang.OutOfMemoryError: Java heap space
第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。
注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
垃圾回收GC的角色
JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:
当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。
根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。
为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收,
一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。
二、JVM内存区域组成
简单的说java中的堆和栈
java把内存分两种:一种是栈内存,另一种是堆内存
1。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
2。堆内存用来存放由new创建的对象和数组
在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;
栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。
java堆分为三个区:New、Old和Permanent
GC有两个线程:
新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn
java栈存放
栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间
每个线程都有他自己的Stack
三、JVM如何设置虚拟内存
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。
简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,
这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC ,大大降低了性能
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.bat
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能检查工具使用
定位内存泄漏:
JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。
1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位;
2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次;
3. 应用服务器经常做Full GC(Garbage Collection),而且时间很长,大约需要30-40秒,应用服务器在做Full GC的时候是不响应客户的交易请求的,非常影响系统性能。
因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生,通常可以使用工具跟踪系统的内存使用情况,在有些个别情况下或许某个时刻确实是使用了大量内存导致out of memory,这时应继续跟踪看接下来是否会有下降,
如果一直居高不下这肯定就因为程序的原因导致内存泄漏。
五、不健壮代码的特征及解决办法
1、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。
对于仍然有指针指向的实例,jvm就不会回收该资源,因为垃圾回收会将值为null的对象作为垃圾,提高GC回收机制效率;
2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域;
String str = "aaa";
String str2 = "bbb";
String str3 = str + str2;//假如执行此次之后str ,str2以后再不被调用,那它就会被放在内存中等待Java的gc去回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销;
3、尽量少用静态变量,因为静态变量是全局的,GC不会回收的;
4、避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;显示的声明数组空间,而且申请数量还极大。
这是一个案例想定供大家警戒
使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误,
检查之后发现问题:组件里的代码
m_totalBytes = m_request.getContentLength();
m_binArray = new byte[m_totalBytes];
问题原因是totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。参考:http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747
5、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
6、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃
7、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。
1、java.lang.OutOfMemoryError: PermGen space
JVM管理两种类型的内存,堆和非堆。堆是给开发人员用的上面说的就是,是在JVM启动时创建;非堆是留给JVM自己用的,用来存放类的信息的。它和堆不同,运行期内GC不会释放空间。如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context更改为新部署的,非堆存的内容就会越来越多。
2、java.lang.OutOfMemoryError: Java heap space
第一种情况是个补充,主要存在问题就是出现在这个情况中。其默认空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。如果内存剩余不到40%,JVM就会增大堆到Xmx设置的值,内存剩余超过70%,JVM就会减小堆到Xms设置的值。所以服务器的Xmx和Xms设置一般应该设置相同避免每次GC后都要调整虚拟机堆的大小。假设物理内存无限大,那么JVM内存的最大值跟操作系统有关,一般32位机是1.5g到3g之间,而64位的就不会有限制了。
注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
垃圾回收GC的角色
JVM调用GC的频度还是很高的,主要两种情况下进行垃圾回收:
当应用程序线程空闲;另一个是java内存堆不足时,会不断调用GC,若连续回收都解决不了内存堆不足的问题时,就会报out of memory错误。因为这个异常根据系统运行环境决定,所以无法预期它何时出现。
根据GC的机制,程序的运行会引起系统运行环境的变化,增加GC的触发机会。
为了避免这些问题,程序的设计和编写就应避免垃圾对象的内存占用和GC的开销。显示调用System.GC()只能建议JVM需要在内存中对垃圾对象进行回收,但不是必须马上回收,
一个是并不能解决内存资源耗空的局面,另外也会增加GC的消耗。
二、JVM内存区域组成
简单的说java中的堆和栈
java把内存分两种:一种是栈内存,另一种是堆内存
1。在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;
2。堆内存用来存放由new创建的对象和数组
在函数(代码块)中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理
堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢;
栈的优势是存取速度比堆要快,缺点是存在栈中的数据大小与生存期必须是确定的无灵活性。
java堆分为三个区:New、Old和Permanent
GC有两个线程:
新创建的对象被分配到New区,当该区被填满时会被GC辅助线程移到Old区,当Old区也填满了会触发GC主线程遍历堆内存里的所有对象。Old区的大小等于Xmx减去-Xmn
java栈存放
栈调整:参数有+UseDefaultStackSize -Xss256K,表示每个线程可申请256k的栈空间
每个线程都有他自己的Stack
三、JVM如何设置虚拟内存
提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。
提示:JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。
提示:假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。
简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,
这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了
提示:注意:如果Xms超过了Xmx值,或者堆最大值和非堆最大值的总和超过了物理内存或者操作系统的最大限制都会引起服务器启动不起来。
提示:设置NewSize、MaxNewSize相等,"new"的大小最好不要大于"old"的一半,原因是old区如果不够大会频繁的触发"主" GC ,大大降低了性能
JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。
解决方法:手动设置Heap size
修改TOMCAT_HOME/bin/catalina.bat
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能检查工具使用
定位内存泄漏:
JProfiler工具主要用于检查和跟踪系统(限于Java开发的)的性能。JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收,线程运行状况等手段,从而很好的监视JVM运行情况及其性能。
1. 应用服务器内存长期不合理占用,内存经常处于高位占用,很难回收到低位;
2. 应用服务器极为不稳定,几乎每两天重新启动一次,有时甚至每天重新启动一次;
3. 应用服务器经常做Full GC(Garbage Collection),而且时间很长,大约需要30-40秒,应用服务器在做Full GC的时候是不响应客户的交易请求的,非常影响系统性能。
因为开发环境和产品环境会有不同,导致该问题发生有时会在产品环境中发生,通常可以使用工具跟踪系统的内存使用情况,在有些个别情况下或许某个时刻确实是使用了大量内存导致out of memory,这时应继续跟踪看接下来是否会有下降,
如果一直居高不下这肯定就因为程序的原因导致内存泄漏。
五、不健壮代码的特征及解决办法
1、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。
对于仍然有指针指向的实例,jvm就不会回收该资源,因为垃圾回收会将值为null的对象作为垃圾,提高GC回收机制效率;
2、我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域;
String str = "aaa";
String str2 = "bbb";
String str3 = str + str2;//假如执行此次之后str ,str2以后再不被调用,那它就会被放在内存中等待Java的gc去回收,程序内过多的出现这样的情况就会报上面的那个错误,建议在使用字符串时能使用StringBuffer就不要用String,这样可以省不少开销;
3、尽量少用静态变量,因为静态变量是全局的,GC不会回收的;
4、避免集中创建对象尤其是大对象,JVM会突然需要大量内存,这时必然会触发GC优化系统内存环境;显示的声明数组空间,而且申请数量还极大。
这是一个案例想定供大家警戒
使用jspsmartUpload作文件上传,运行过程中经常出现java.outofMemoryError的错误,
检查之后发现问题:组件里的代码
m_totalBytes = m_request.getContentLength();
m_binArray = new byte[m_totalBytes];
问题原因是totalBytes这个变量得到的数极大,导致该数组分配了很多内存空间,而且该数组不能及时释放。解决办法只能换一种更合适的办法,至少是不会引发outofMemoryError的方式解决。参考:http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747
5、尽量运用对象池技术以提高系统性能;生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。
6、不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃
7、一般都是发生在开启大型文件或跟数据库一次拿了太多的数据,造成 Out Of Memory Error 的状况,这时就大概要计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。
2008年7月30日星期三
(ZT)Java 调用 https webservice
Java 要调用远程Https webservice 必需具用远程服务器提供的客户端信任书及密钥.
将client.keystore和client.truststore拷贝到classes\test目录下.
package test;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class TestEcVoteNotice
{
public static void main(String [] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "test\\client.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "abc");
System.setProperty("javax.net.ssl.trustStore", "test\\client.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "abc");
String endpoint = "https://localhost:" +"8443"+ "/axis/services/EcVoteNotice";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName("toStringP");
String res = (String) call.invoke( new Object[] {"Box"} );
call.setOperationName("toString");
String res2 = (String) call.invoke( new Object[] {} );
System.out.println( res+"/"+res2 );
}
}
在classes目录下执行.
java -cp %AXISCLASSPATH% test.TestEcVoteNotice
Refrence: http://wwwww.javaeye.com/blog/94854
将client.keystore和client.truststore拷贝到classes\test目录下.
package test;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class TestEcVoteNotice
{
public static void main(String [] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "test\\client.keystore");
System.setProperty("javax.net.ssl.keyStorePassword", "abc");
System.setProperty("javax.net.ssl.trustStore", "test\\client.truststore");
System.setProperty("javax.net.ssl.trustStorePassword", "abc");
String endpoint = "https://localhost:" +"8443"+ "/axis/services/EcVoteNotice";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName("toStringP");
String res = (String) call.invoke( new Object[] {"Box"} );
call.setOperationName("toString");
String res2 = (String) call.invoke( new Object[] {} );
System.out.println( res+"/"+res2 );
}
}
在classes目录下执行.
java -cp %AXISCLASSPATH% test.TestEcVoteNotice
Refrence: http://wwwww.javaeye.com/blog/94854
2008年7月23日星期三
下载文件
下载文件的代码,不论格式,从碰盘将文件读出来,下载
response.setContentType("application/x-download");//设置为下载application/x-download
response.addHeader("Content-Disposition","attachment;filename=" + filePath);
OutputStream outputStream = response.getOutputStream();
String fileRealPath = "";
fileRealPath = siteRealPath + filePath;
InputStream inputStream = new FileInputStream(fileRealPath);
byte[] buffer = new byte[1024];
int i = -1;
while ((i = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, i);
}
outputStream.flush();
outputStream.close();
response.setContentType("application/x-download");//设置为下载application/x-download
response.addHeader("Content-Disposition","attachment;filename=" + filePath);
OutputStream outputStream = response.getOutputStream();
String fileRealPath = "";
fileRealPath = siteRealPath + filePath;
InputStream inputStream = new FileInputStream(fileRealPath);
byte[] buffer = new byte[1024];
int i = -1;
while ((i = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, i);
}
outputStream.flush();
outputStream.close();
2008年7月22日星期二
mysql+proxool经常出现数据库连接异常
mysql+proxool经常出现数据库连接异常
原因:
1. 如果一段时间(默认 8 小时)不访问应用(数据库),则 mysql 的连接会自动断开,下次连接的时候,就需要重新建立连接才可以访问
解决方法:
1. 设置 mysql 的默认断开时间, 启动 ini 文件中的 wait_timeout 参数,以秒计,如下表示两小时
wait_timeout = 7200
2. 设置 proxool.xml 文件
a. drive-url 应该增加 autoReconnect 参数,如下:
jdbc:mysql://localhost:3308/secfox_som?autoReconnect=true
b. proxool 结点下应该增加两行,如下:
60000
select CURRENT_DATE
第一个参数以 ms 计,表示多长时间后自动重新连接,以保持连接,本例中表示 60 秒(这个时间应该比 第 1 步中的 wait_timeout 短)
第二个参数,表示用什么 sql 语句来自动连接数据库
原因:
1. 如果一段时间(默认 8 小时)不访问应用(数据库),则 mysql 的连接会自动断开,下次连接的时候,就需要重新建立连接才可以访问
解决方法:
1. 设置 mysql 的默认断开时间, 启动 ini 文件中的 wait_timeout 参数,以秒计,如下表示两小时
wait_timeout = 7200
2. 设置 proxool.xml 文件
a. drive-url 应该增加 autoReconnect 参数,如下:
jdbc:mysql://localhost:3308/secfox_som?autoReconnect=true
b. proxool 结点下应该增加两行,如下:
第一个参数以 ms 计,表示多长时间后自动重新连接,以保持连接,本例中表示 60 秒(这个时间应该比 第 1 步中的 wait_timeout 短)
第二个参数,表示用什么 sql 语句来自动连接数据库
2008年5月27日星期二
Android 是什么
http://baike.baidu.com/view/1241829.htm
Android是什么?
android
n.
(1) (科学幻想小说中的)机器人
(2)人造人,男性样的
Android同时也是Google于07年11月5日宣布的Google自己研发的手机平台操作系统的名称
该平台基于开源软件Linux,由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。
Android介绍
Android 是一个真正意义上的开放性移动设备综合平台。它包括操作系统、用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。谷歌与开放手机联盟合作开发了 Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达和 T-Mobile 在内的 30 多家技术和无线应用的领军企业组成。通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,我们希望借助建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统。我们认为此举必将推进更好、更快的创新,为移动用户提供不可预知的应用和服务。
Android 作为谷歌企业战略的重要组成部分,将进一步推进"随时随地为每个人提供信息"这一企业目标的实现。我们发现,全球为数众多的移动电话用户从未使用过任何基于 Android 的电话。谷歌的目标是让(移动通讯)不依赖于设备甚至平台。出于这个目的,Android 将补充,而不会替代谷歌长期以来奉行的移动发展战略:通过与全球各地的手机制造商和移动运营商结成合作伙伴,开发既有用又有吸引力的移动服务,并推广这些产品。
开放手机联盟的成立和 Android 的推出是对现状的重大改变,在带来初步效益之前,还需要不小的耐心和高昂的投入。但是,我们认为全球移动用户从中能获得的潜在利益是值得付出这些努力的。如果你也是一个开发者,并对我们的想法感兴趣,就请再给我们一星期的时间,届时谷歌便能提供 SDK 了。如果你是一名移动用户,只需再等一段时间,我们的一些合作伙伴计划在 2008 年下半年推出基于 Android 平台的电话产品。如果你已经拥有一部你了解并喜爱的电话,请登录 mobile.google.com ,确保你已经安装谷歌手机地图、Gmail 以及其他一些专为你的手机开发的精彩应用。谷歌将继续努力,让这些服务变得更好,同时也将添加更有吸引力的特性、应用和服务。
Android的团队
Android平台的研发队伍阵容强大,包括Google、HTC(宏达电)、T-Mobile、高通、摩托罗拉、三星、LG以及中国移动在内的34家企业都将基于该平台开发手机的新型业务,应用之间的通用性和互联性将在最大程度上得到保持。“开放手机联盟”表示,Android平台可以促使移动设备的创新,让用户体验到最优越的移动服务,同时,开发商也将得到一个新的开放级别,更方便的进行协同合作,从而保障新型移动设备的研发速度。
34家企业的加盟,也将大大降低新型手机设备的研发成本,完全整合的“全移动功能性产品”成为“开放手机联盟”的最终目标。
这34家企业中并不包含全球手机第一巨头诺基亚,把持UIQ平台的索尼爱立信,以及凭借着iPhone风光正在的苹果公司,美国运营商AT&T和Verizon,当然微软没有加入,独树一帜的加拿大RIM和他们的Blackberry也被挡在门外。
Android的未来
虽然没有看到Gphone的真正模样,但据了解,Google的Android平台手机将在2008年下半年正式揭开面纱.对于消费者来说,Google手机将是一款通用的、功能强大的、设备完整的手机产品。
美国咨询研究集团Strategy Analytics的最新报告指出,Google最近公布的android手机软件平台,很可能在2008年时获得全球智能手机软件平台2%的份额。
而老牌智能手机软件平台制造商Symbian发言人则表示:Google的android只不过是另一个linux,symbian对其它软件与其形成的竞争并不感到担心。除了北美之外,Symbian在其它地区智能手机市场都占有大部分市场份额。
究竟Android的未来如何,让我们拭目以待!
如何学习Android
看了看Android Blog, 在最新的文章里面介绍了几篇文章,其中一篇是<<以开发者的眼光来看Android SDK>>,作者在其中分析了的关于DOC的阅读顺序引起了我的兴趣,确实,那么多的文档,应该怎么看呢?哪些是必须先弄明白的?哪些应该先知道个大概,今后引用的时候再细细阅读?现在简要的介绍一下原作者的观点,希望能帮上你的忙。
1. 首先当然是要知道,什么是Android?
2. 读一下Anatomy of an Android Application 能够知道一个Android application 中到底都有些什么东西
3. 接着可以读一下 Development Tools 文档
4. 然后可以看一下关于什么周期的文章 Lifecycle of an Android Application
5. 现在可以动手了,玩玩hello world 吧,Hello Android
6. 回去读一下 Installing the SDK文档,再这篇文章的后半部分讲了很多关于Debug的功能和技巧
7. 开始Notepad Application 的制作和学习吧,如果你真正弄懂了关于这个应用程序的4个练习,你已经从菜鸟开始转向高手喽。
8. Developing Android Applications 花了很多时间来介绍更多的细节,包括如何实现UI,数据存储和读取,安全问题等
9. 最后,你现在可以自由的漫步在links中了,找你感兴趣的读读吧。
希望我们大家一起学习 Android
Android是什么?
android
n.
(1) (科学幻想小说中的)机器人
(2)人造人,男性样的
Android同时也是Google于07年11月5日宣布的Google自己研发的手机平台操作系统的名称
该平台基于开源软件Linux,由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放和完整的移动软件。
Android介绍
Android 是一个真正意义上的开放性移动设备综合平台。它包括操作系统、用户界面和应用程序 —— 移动电话工作所需的全部软件,而且不存在任何以往阻碍移动产业创新的专有权障碍。谷歌与开放手机联盟合作开发了 Android,这个联盟由包括中国移动、摩托罗拉、高通、宏达和 T-Mobile 在内的 30 多家技术和无线应用的领军企业组成。通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,我们希望借助建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统。我们认为此举必将推进更好、更快的创新,为移动用户提供不可预知的应用和服务。
Android 作为谷歌企业战略的重要组成部分,将进一步推进"随时随地为每个人提供信息"这一企业目标的实现。我们发现,全球为数众多的移动电话用户从未使用过任何基于 Android 的电话。谷歌的目标是让(移动通讯)不依赖于设备甚至平台。出于这个目的,Android 将补充,而不会替代谷歌长期以来奉行的移动发展战略:通过与全球各地的手机制造商和移动运营商结成合作伙伴,开发既有用又有吸引力的移动服务,并推广这些产品。
开放手机联盟的成立和 Android 的推出是对现状的重大改变,在带来初步效益之前,还需要不小的耐心和高昂的投入。但是,我们认为全球移动用户从中能获得的潜在利益是值得付出这些努力的。如果你也是一个开发者,并对我们的想法感兴趣,就请再给我们一星期的时间,届时谷歌便能提供 SDK 了。如果你是一名移动用户,只需再等一段时间,我们的一些合作伙伴计划在 2008 年下半年推出基于 Android 平台的电话产品。如果你已经拥有一部你了解并喜爱的电话,请登录 mobile.google.com ,确保你已经安装谷歌手机地图、Gmail 以及其他一些专为你的手机开发的精彩应用。谷歌将继续努力,让这些服务变得更好,同时也将添加更有吸引力的特性、应用和服务。
Android的团队
Android平台的研发队伍阵容强大,包括Google、HTC(宏达电)、T-Mobile、高通、摩托罗拉、三星、LG以及中国移动在内的34家企业都将基于该平台开发手机的新型业务,应用之间的通用性和互联性将在最大程度上得到保持。“开放手机联盟”表示,Android平台可以促使移动设备的创新,让用户体验到最优越的移动服务,同时,开发商也将得到一个新的开放级别,更方便的进行协同合作,从而保障新型移动设备的研发速度。
34家企业的加盟,也将大大降低新型手机设备的研发成本,完全整合的“全移动功能性产品”成为“开放手机联盟”的最终目标。
这34家企业中并不包含全球手机第一巨头诺基亚,把持UIQ平台的索尼爱立信,以及凭借着iPhone风光正在的苹果公司,美国运营商AT&T和Verizon,当然微软没有加入,独树一帜的加拿大RIM和他们的Blackberry也被挡在门外。
Android的未来
虽然没有看到Gphone的真正模样,但据了解,Google的Android平台手机将在2008年下半年正式揭开面纱.对于消费者来说,Google手机将是一款通用的、功能强大的、设备完整的手机产品。
美国咨询研究集团Strategy Analytics的最新报告指出,Google最近公布的android手机软件平台,很可能在2008年时获得全球智能手机软件平台2%的份额。
而老牌智能手机软件平台制造商Symbian发言人则表示:Google的android只不过是另一个linux,symbian对其它软件与其形成的竞争并不感到担心。除了北美之外,Symbian在其它地区智能手机市场都占有大部分市场份额。
究竟Android的未来如何,让我们拭目以待!
如何学习Android
看了看Android Blog, 在最新的文章里面介绍了几篇文章,其中一篇是<<以开发者的眼光来看Android SDK>>,作者在其中分析了的关于DOC的阅读顺序引起了我的兴趣,确实,那么多的文档,应该怎么看呢?哪些是必须先弄明白的?哪些应该先知道个大概,今后引用的时候再细细阅读?现在简要的介绍一下原作者的观点,希望能帮上你的忙。
1. 首先当然是要知道,什么是Android?
2. 读一下Anatomy of an Android Application 能够知道一个Android application 中到底都有些什么东西
3. 接着可以读一下 Development Tools 文档
4. 然后可以看一下关于什么周期的文章 Lifecycle of an Android Application
5. 现在可以动手了,玩玩hello world 吧,Hello Android
6. 回去读一下 Installing the SDK文档,再这篇文章的后半部分讲了很多关于Debug的功能和技巧
7. 开始Notepad Application 的制作和学习吧,如果你真正弄懂了关于这个应用程序的4个练习,你已经从菜鸟开始转向高手喽。
8. Developing Android Applications 花了很多时间来介绍更多的细节,包括如何实现UI,数据存储和读取,安全问题等
9. 最后,你现在可以自由的漫步在links中了,找你感兴趣的读读吧。
希望我们大家一起学习 Android
今年需要关注学习的一些技术
OSGI
GWT
Groovy
JCR - apache JackRabbit
Android
Hibernate/Spring/Guice
Scala
考虑一下有哪些产品可以做 合购?finding Job? web shop? cms ?
GWT
Groovy
JCR - apache JackRabbit
Android
Hibernate/Spring/Guice
Scala
考虑一下有哪些产品可以做 合购?finding Job? web shop? cms ?
2008年5月9日星期五
js和java applet相互调用
js调用java
可以在网页里使用
可以对applet进行控制,也可以从applet返回值。
返回值无需关心值得类型,js会隐式的转换。
传值到applet中应考虑类型匹配。
java调用js
需要导入netscape.javascript.jsobject这个类
比如:
JSObject window=JSObject.getWindow(this);
JSObject window=(JSObject)window.getMember("document");
来获取对当前窗口的控制权。
可以在网页里使用
可以对applet进行控制,也可以从applet返回值。
返回值无需关心值得类型,js会隐式的转换。
传值到applet中应考虑类型匹配。
java调用js
需要导入netscape.javascript.jsobject这个类
比如:
JSObject window=JSObject.getWindow(this);
JSObject window=(JSObject)window.getMember("document");
来获取对当前窗口的控制权。
如何采用js调用本地程序
如何采用js调用本地程序
<script language=\"javascript\">
function exec(command)
{
window.oldOnError = window.onerror;
window._command = command;
window.onerror = function (err) {
if (err.indexOf(\'utomation\') != -1)
{
alert(\'命令\' + window._command + \' 已经被用户禁止!\');
return true;
}
else
return false;
};
//-----------
var wsh = new ActiveXObject(\'WScript.Shell\');
if (wsh) wsh.Run(command);
wsh = null;
window.onerror = window.oldOnError;
}
</script>
<input type=\"button\" value=\"执行\" onclick=\"exec(\'telnet.exe\')\" />
<script language=\"javascript\">
function exec(command)
{
window.oldOnError = window.onerror;
window._command = command;
window.onerror = function (err) {
if (err.indexOf(\'utomation\') != -1)
{
alert(\'命令\' + window._command + \' 已经被用户禁止!\');
return true;
}
else
return false;
};
//-----------
var wsh = new ActiveXObject(\'WScript.Shell\');
if (wsh) wsh.Run(command);
wsh = null;
window.onerror = window.oldOnError;
}
</script>
<input type=\"button\" value=\"执行\" onclick=\"exec(\'telnet.exe\')\" />
2008年4月30日星期三
内存泄漏的问题
近来项目发现内存泄漏问题严重,花了两天多时间才解决
修改前,实时分析雷达图每 10 秒刷新一次,内存同时增长 2M 左右
问题主要在两个地方,第一个地方占用内存最大,修改完成后,内存的增长速度降到 每分钟增长 2M 左右,第二个地方修改完成后,现在我本机测试已经看不出明显的内存增长了
内存泄漏的原因有多种,但最主要的泄漏就是 DOM 域与 js 域相互引用以及内部函数,现在我们修改的地方也是这种情况,其实如果不是经常刷新,应该问题不大,只要重启 IE 就可以释放,但我们需要不停的刷新,所以问题比较明显.
比如下面的代码:
代码一(内部函数):
function AttachEvents(element)
{
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", ClickEventHandler);
function ClickEventHandler()
{
// This closure refs element
}
}
}
//调用此函数就会发生泄漏
function SetupLeak()
{
AttachEvents(document.getElementById("LeakedDiv"));
}
代码二(dom 跟 js 相互引用):
document.createElement("");
或者:
document.createElement("");
fuction a(){...}
1. WEB-INF/pages/sim/analyse/view/sceneEventList.jsp
有两处代码需要修改,这两处代码类似,下面是其中一处的代码及修改后的代码:
原代码:
$("headerContainer").childElements().invoke("remove");
$("headerContainer").innerHTML = headerHTML;
现代码:
$("headerContainer").innerHTML = null;
$("headerContainer").innerHTML = headerHTML;
2. web/common/scrollTable.jsp
在函数 initColumnResizer(...) 中内部建了函数
原代码:
var resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......
resizeBar.onmouseout = function() {
this.style.cursor = 'default';
};
.......
问题主要就在类似于 resizeBar.onmouseout = function(){...} 这样的代码上,DOM 对象 resizeBar 直接定义了函数 function,此处类似的函数一共是 6 个
解决方法就是将这些函数单独拿出来,然后再引用
现代码:
在 initColumnResizer 函数外新定义函数 mouseout 等函数,如下:
function mouseout(){
.......
}
然后在 initColumnResizer 函数中原来引用这些函数的地方用下面的代码替换:
rezeBar = null;
resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......
resizeBar.onmouseover = mouseover;
resizeBar.onmouseout = mouseout;
resizeBar.onclick = mouseclick;
resizeBar.onmousedown = mousedown;
resizeBar.onmousemove = mousemove;
resizeBar.onmouseup = mouseup;
修改前,实时分析雷达图每 10 秒刷新一次,内存同时增长 2M 左右
问题主要在两个地方,第一个地方占用内存最大,修改完成后,内存的增长速度降到 每分钟增长 2M 左右,第二个地方修改完成后,现在我本机测试已经看不出明显的内存增长了
内存泄漏的原因有多种,但最主要的泄漏就是 DOM 域与 js 域相互引用以及内部函数,现在我们修改的地方也是这种情况,其实如果不是经常刷新,应该问题不大,只要重启 IE 就可以释放,但我们需要不停的刷新,所以问题比较明显.
比如下面的代码:
代码一(内部函数):
function AttachEvents(element)
{
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", ClickEventHandler);
function ClickEventHandler()
{
// This closure refs element
}
}
}
//调用此函数就会发生泄漏
function SetupLeak()
{
AttachEvents(document.getElementById("LeakedDiv"));
}
代码二(dom 跟 js 相互引用):
document.createElement("");
或者:
document.createElement("");
fuction a(){...}
1. WEB-INF/pages/sim/analyse/view/sceneEventList.jsp
有两处代码需要修改,这两处代码类似,下面是其中一处的代码及修改后的代码:
原代码:
$("headerContainer").childElements().invoke("remove");
$("headerContainer").innerHTML = headerHTML;
现代码:
$("headerContainer").innerHTML = null;
$("headerContainer").innerHTML = headerHTML;
2. web/common/scrollTable.jsp
在函数 initColumnResizer(...) 中内部建了函数
原代码:
var resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......
resizeBar.onmouseout = function() {
this.style.cursor = 'default';
};
.......
问题主要就在类似于 resizeBar.onmouseout = function(){...} 这样的代码上,DOM 对象 resizeBar 直接定义了函数 function,此处类似的函数一共是 6 个
解决方法就是将这些函数单独拿出来,然后再引用
现代码:
在 initColumnResizer 函数外新定义函数 mouseout 等函数,如下:
function mouseout(){
.......
}
然后在 initColumnResizer 函数中原来引用这些函数的地方用下面的代码替换:
rezeBar = null;
resizeBar = document.createElement('DIV');
resizeBar.style.backgroundColor = 'transparent';
.......
resizeBar.onmouseover = mouseover;
resizeBar.onmouseout = mouseout;
resizeBar.onclick = mouseclick;
resizeBar.onmousedown = mousedown;
resizeBar.onmousemove = mousemove;
resizeBar.onmouseup = mouseup;
2008年4月23日星期三
闭包函数导到 IE 内存泄漏
闭包函数是一个内部的函数,可以理解为函数里的函数,如下面代码一中的 ClickEventHandler 函数
如果闭包函数引用了外部变量,那么,闭包函数运行完毕后,可能并不会释放该变量,于是会导致内存泄漏
代码一:
<html>
<head>
<script language="JScript">
function AttachEvents(element)
{
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", ClickEventHandler);
function ClickEventHandler()
{
// This closure refs element
}
}
function SetupLeak()
{
// The leak happens all at once
AttachEvents(document.getElementById("LeakedDiv"));
}
function BreakLeak()
{
}
</script>
</head>
<body onload="SetupLeak()" onunload="BreakLeak()">
<div id="LeakedDiv"></div>
</body>
</html>
解决方法就是将闭包函数先放入一个变量,这样,当它执行完成后,它仍然在内存中存在,然后再显式地释放它,如代码二:
<html>
<head>
<script language="JScript">
function AttachEvents(element)
{
// In order to remove this we need to put
// it somewhere. Creates another ref
element.expandoClick = ClickEventHandler;
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", element.expandoClick);
function ClickEventHandler()
{
// This closure refs element
}
}
function SetupLeak()
{
// The leak happens all at once
AttachEvents(document.getElementById("LeakedDiv"));
}
//释放内存
function BreakLeak()
{
document.getElementById("LeakedDiv").detachEvent("onclick",
document.getElementById("LeakedDiv").expandoClick);
document.getElementById("LeakedDiv").expandoClick = null;
}
</script>
</head>
<body onload="SetupLeak()" onunload="BreakLeak()">
<div id="LeakedDiv"></div>
</body>
</html>
闭包函数是一个内部的函数,可以理解为函数里的函数,如下面代码一中的 ClickEventHandler 函数
如果闭包函数引用了外部变量,那么,闭包函数运行完毕后,可能并不会释放该变量,于是会导致内存泄漏
代码一:
<html>
<head>
<script language="JScript">
function AttachEvents(element)
{
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", ClickEventHandler);
function ClickEventHandler()
{
// This closure refs element
}
}
function SetupLeak()
{
// The leak happens all at once
AttachEvents(document.getElementById("LeakedDiv"));
}
function BreakLeak()
{
}
</script>
</head>
<body onload="SetupLeak()" onunload="BreakLeak()">
<div id="LeakedDiv"></div>
</body>
</html>
解决方法就是将闭包函数先放入一个变量,这样,当它执行完成后,它仍然在内存中存在,然后再显式地释放它,如代码二:
<html>
<head>
<script language="JScript">
function AttachEvents(element)
{
// In order to remove this we need to put
// it somewhere. Creates another ref
element.expandoClick = ClickEventHandler;
// This structure causes element to ref ClickEventHandler
element.attachEvent("onclick", element.expandoClick);
function ClickEventHandler()
{
// This closure refs element
}
}
function SetupLeak()
{
// The leak happens all at once
AttachEvents(document.getElementById("LeakedDiv"));
}
//释放内存
function BreakLeak()
{
document.getElementById("LeakedDiv").detachEvent("onclick",
document.getElementById("LeakedDiv").expandoClick);
document.getElementById("LeakedDiv").expandoClick = null;
}
</script>
</head>
<body onload="SetupLeak()" onunload="BreakLeak()">
<div id="LeakedDiv"></div>
</body>
</html>
闭包函数导致 IE 内存泄漏
闭包函数导到 IE 内存泄漏
闭包函数是一个内部的函数,可以理解为函数里的函数,如下面代码一中的 ClickEventHandler 函数如果闭包函数引用了外部变量,那么,闭包函数运行完毕后,可能并不会释放该变量,于是会导致内存泄漏
代码一:
解决方法就是将闭包函数先放入一个变量,这样,当它执行完成后,它仍然在内存中存在,然后再显式地释放它,如代码二:
闭包函数是一个内部的函数,可以理解为函数里的函数,如下面代码一中的 ClickEventHandler 函数如果闭包函数引用了外部变量,那么,闭包函数运行完毕后,可能并不会释放该变量,于是会导致内存泄漏
代码一:
解决方法就是将闭包函数先放入一个变量,这样,当它执行完成后,它仍然在内存中存在,然后再显式地释放它,如代码二:
2008年4月8日星期二
使用开源网格计算平台-GridGain实现网格计算
From: http://blog.csdn.net/danny_xcz/archive/2007/05/24/1623536.aspx
网格计算一般分为两种:数据网格和计算网格,简单的说数据网格就是把数据分布式存储,计算网格就是将任务分解为子认为并行计算。
一个计算网格平台的作用就是将任务分解开来,交给不同的结点机器运行,然后把运行结果汇聚起来。这就是Split and Aggregate。如下图所示,一个job请求分解为三个sub-job,分别被不同的机器执行,然后把结果汇聚,返回给调用的客户。

GridGain是一个开源的java网格平台。它集成了很多现成的框架,例如
JBoss
Spring
Spring AOP
JBoss AOP
AspectJ
JGroups
GridGain有两个方法将应用程序grid化:
第一种是使用AOP
假设有一个应用
01 class BizLogic {
02 public static Result process(String param) {
03 …
04 }
05 }
06
07 class Caller {
08 public static void Main(String[] args) {
09 BizLogic.process(args[0]);
10 }
11 }
如果要把process grid化,只要简单的使用一个@Gridify的annotation即可,在Caller客户端要启动GridFactory
01 class BizLogic {
02 @Gridify(…)Here
03 public static Result process(String param) {
04 …
05 }
06 }
07
08 class Caller {
09 public static void Main(String[] args) {
10 GridFactory.start();Here
11
12 try {
13 BizLogic.process(args[0]);
14 }
15 finally {
16 GridFactory.stop();Here
17 }
18 }
19 }
这是最简单,不破坏原有业务逻辑的方法,还有一种方法如果要实现复杂些的任务分解,扩展GridifyJobAdaptor基类,实现split 和aggregate 接口
网格计算一般分为两种:数据网格和计算网格,简单的说数据网格就是把数据分布式存储,计算网格就是将任务分解为子认为并行计算。
一个计算网格平台的作用就是将任务分解开来,交给不同的结点机器运行,然后把运行结果汇聚起来。这就是Split and Aggregate。如下图所示,一个job请求分解为三个sub-job,分别被不同的机器执行,然后把结果汇聚,返回给调用的客户。

GridGain是一个开源的java网格平台。它集成了很多现成的框架,例如
JBoss
Spring
Spring AOP
JBoss AOP
AspectJ
JGroups
GridGain有两个方法将应用程序grid化:
第一种是使用AOP
假设有一个应用
01 class BizLogic {
02 public static Result process(String param) {
03 …
04 }
05 }
06
07 class Caller {
08 public static void Main(String[] args) {
09 BizLogic.process(args[0]);
10 }
11 }
如果要把process grid化,只要简单的使用一个@Gridify的annotation即可,在Caller客户端要启动GridFactory
01 class BizLogic {
02 @Gridify(…)Here
03 public static Result process(String param) {
04 …
05 }
06 }
07
08 class Caller {
09 public static void Main(String[] args) {
10 GridFactory.start();Here
11
12 try {
13 BizLogic.process(args[0]);
14 }
15 finally {
16 GridFactory.stop();Here
17 }
18 }
19 }
这是最简单,不破坏原有业务逻辑的方法,还有一种方法如果要实现复杂些的任务分解,扩展GridifyJobAdaptor基类,实现split 和aggregate 接口
2008年3月25日星期二
JFreeChart 渐变色的设置
最近同事写代码的时候发现 JFreechart 柱图设置渐变色的时候,水平方向的柱图无论怎么设点都不管用,查看 JFreechart 源码后发现一些问题.
默认的情况下,jfreechart是纵向渐变。JFreeChart 的渐变利用的是 GradientPaint 类,这是java的标准类。它的参数为(x1,y1,color1,x2,y2,color2),颜色是从x1,y1的点向x2,y2的点进行颜色渐变。但用在jfreechart中无论你如何设置这两点都没有作用。原因是它在内部重新定义GradientPaint对象。颜色是用我们定义的颜色,点是由它自己设置(也就是说不用我们自己设点?)。原因很简单,就是我们传递GradientPaint对象给renderer时,并不知道它的柱子会画多高(如果是水平就是多宽),所以它在画柱子时,会把柱子的开始点与高度重新传给新的GradientPaint对象。
jfreechart中控制渐变的横向与纵向的开关就是StandardGradientPaintTransformer对象,在new这个对象时,有一个带参的构造函数,可以把纵向或横向传递进去,如下代码所示:
//首先要得到BarRenderer 对象,如果使用的是CategoryItemRenderer,那需要进行转换了。因为下面的方法只有BarRender才有。
BarRenderer renderer = (BarRenderer)chart.getCategoryPlot().getRenderer();
if (!vertical) {
StandardGradientPaintTransformer transformer = new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL);
renderer.setGradientPaintTransformer(transformer);
}
if (vertical) {
renderer.setSeriesPaint(0, new GradientPaint(0.0F, 0.0F, Color.blue, 0.0F, 0.0F, Color.lightGray));
}
else {
renderer.setSeriesPaint(0, new GradientPaint(0.0F, 0.0F, Color.lightGray, (float)width, (float)height, Color.blue));
}
默认的情况下,jfreechart是纵向渐变。JFreeChart 的渐变利用的是 GradientPaint 类,这是java的标准类。它的参数为(x1,y1,color1,x2,y2,color2),颜色是从x1,y1的点向x2,y2的点进行颜色渐变。但用在jfreechart中无论你如何设置这两点都没有作用。原因是它在内部重新定义GradientPaint对象。颜色是用我们定义的颜色,点是由它自己设置(也就是说不用我们自己设点?)。原因很简单,就是我们传递GradientPaint对象给renderer时,并不知道它的柱子会画多高(如果是水平就是多宽),所以它在画柱子时,会把柱子的开始点与高度重新传给新的GradientPaint对象。
jfreechart中控制渐变的横向与纵向的开关就是StandardGradientPaintTransformer对象,在new这个对象时,有一个带参的构造函数,可以把纵向或横向传递进去,如下代码所示:
//首先要得到BarRenderer 对象,如果使用的是CategoryItemRenderer,那需要进行转换了。因为下面的方法只有BarRender才有。
BarRenderer renderer = (BarRenderer)chart.getCategoryPlot().getRenderer();
if (!vertical) {
StandardGradientPaintTransformer transformer = new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL);
renderer.setGradientPaintTransformer(transformer);
}
if (vertical) {
renderer.setSeriesPaint(0, new GradientPaint(0.0F, 0.0F, Color.blue, 0.0F, 0.0F, Color.lightGray));
}
else {
renderer.setSeriesPaint(0, new GradientPaint(0.0F, 0.0F, Color.lightGray, (float)width, (float)height, Color.blue));
}
2008年2月25日星期一
订阅:
博文 (Atom)