jackson json-lib配合完成xml json互换
前段时间优化性能,将原来用的json-lib转换为了jackson,现在要解析xml,发现jaconson解析xml有问题,它对数组元素直解析最后一个,真不知是出于什么考虑?
而json-lib则没有这个问题,但是json-lib输出的json格式有些多余的双引号转义,不是很标准,它生成的json是无法让jackson解析的。
尝试了xstream,要自己写代码解析,不能用。
最后只好两个结合起来用:
Continue reading jackson json-lib配合完成xml json互换 原来的vps(justhost)主机到期了,续费价格翻了4倍几乎300刀两年,这不宰人么,弃之。 听说hostigation.com不错,且我测试ping值是比较快的,200ms平均,就买下了,30刀一年128M内存,想想一个小博客应该够了。 而今: ping值奇怪的平均400ms,内存不是很够,mysql使用的最小内存配置,还是不行,经常无反应,现在博客响应速度很慢呢。还真不如我当初使用的某个二道贩子的20软妹币一年的,真上当了。 折腾一番后,把apache一些模块禁止掉了,一下在节约了60M内存,再一测,速度还行。但是运行个查询就又没内存了。 ping值按时间段不是很稳定,上次测得很慢,这次测又回到了200ms。 参见: 基于wordpress优化apache性能: https://thethemefoundry.com/blog/optimize-apache-wordpress/ Continue reading hostigation.com vps主机使用吐槽 in 默认分类 on google drive, mac, onenote onenote mac版推出了,马上使用一下,结果发现功能很多被阉割。但是还是不错的。 我还是决定弃用: 1:不能粘贴网页格式,网页上粘贴的内容拷贝进去格式全没了。 2:不能插入图片,点击插入图片,只见一个红叉叉,这有什么用? 还是用google drive。 google drive mac版居然能下载下来,居然速度还可以。但是文件同步什么的还是不喜欢,直接网页版上写吧。 ======================================= 今天通知onenote更新了,居然添加了上面的两个功能,难道微软在倾听用户的声音? 纠结要不要把google上的都转过来!! ============================= 发现onenote急需要改进的地方:表格功能太弱,不能合并单元格等等…… Continue reading onenote mac 免费版使用 转自 jloser.com/java对象占用内存大小的分析与计算/ (不知为什么google 报攻击站点) new Object()将占用多少bytes的内存空间?可能大部分时候我们并不是很关心,但是经常有Java开发人员抱怨我们的应用程序越来越慢、越来越消耗内存,特别是在我们面临有限内存和应用功能不断增加的情况下;另一方面,我们在设计应用程序时又常常为对象创建是采用prototype还是singleton方式而犹豫不决。此时,我们有必要搞清楚,运行我们的应用程序究竟需要多少内存预算,而最消耗内存的又是哪些地方和哪些对象。通常,我们遇到这样的问题首先会想到使用Profiler工具来剖析下我们的应用程序,如JProfiler、VisualVM之类,这类工具能够胜任这项工作,但它们具有一定的学习门槛、操作过于复杂、无法与应用集成、本身也很耗内存。如果我们有个像c中的sizeof函数就好了,很不幸,Java没有,好在JDK1.5中发布了一个Instrumentation组件,我们可以借此来自定义一个sizeof工具来测量对象占用的内存大小。首先,在测试之前让我们理论分析下不同Java对象对内存的占用。 一. 须知事项: ——————————————————————————————– 1. 我们所说的Java对象占用内存大小仅是指分配在heap上的对象,在某些情况下JVM可能会在stack上或register上直接为对象分配存储区域,此外静态变量(static)是分配在method area上的; 2. Java对象占用的内存大小在同一JVM内不同时间可能会发生变化, 这主要是内存占用还跟对象的状态有关,如当前对象内置锁的状态、是否正在等待GC回收等; 3. 不同JVM里同样数据结构的对象占用的内存大小也有可能不一样大,这主要是内存占用还跟JVM实现、操作系统等有关。 二. 计算方法: ——————————————————————————————– 1. 通常我们想到的是借助Runtime#freeMemory(), 伪代码如下: long before = Runtime.getRuntime().freeMemory(); Object obj = new Object(); long after = Runtime.getRuntime().freeMemory(); System.out.println("Object size: [" + (after - before) + "]"); 2. 使用序列化技术将对象序列化成byte数组,再检查数组的长度。 3. 使用Reflection API遍历对象所有的fields然后累加。 4. 借助Instrumentation#getObjectSize(Object objectToSize) 计算。 方法1受GC的影响,准确度较低,有时会得出负值;方法2是错误的,序列化的结果是种特定格式的数据,这种格式在多JVM间兼容,但是这种格式的数据在内存中占用的空间大小与序列化后的结果无关;方法3设计复杂,且需要了解JVM实现;方法4简单明了,官方API,可靠,也是本文底层采用的方法。 三. 计算范围: ——————————————————————————————– 1. Shallow, 仅计算为本对象本身新分配的内存大小。 2. Deep, 计算本对象本身及引用对象、引用对象的引用…所有关联对象占用的内存大小。 四. 原生类型(primitive type)的内存占用 Primitive Type Memory Required(bytes) ————————————————————— boolean 1 byte 1 short 2 char 2 int 4 float 4 long 8 double 8 ————————————————————— 五. 对象类型(reference type)的内存占用 下文中的32位(64位)系统是指32位(64位)的JVM。 ——————————————————————————————– 1. 一个object header, 也称object overhead, 保存当前实例的type信息和内置monitor信息等, 32位系统上占用8bytes,64位系统上占用16bytes; 2. 0到多个fields, reference类型在32位系统上每个占用4bytes, 在64位系统上每个占用8bytes; primitive类型参考上面; 3. padding, 对步骤1、2之和的补长。CPU从内存中读取数据是以word为基本单位, 32位的系统中word宽度为32bits, 64位的系统中word宽度为64bits, 将整个Java对象占用内存补长为word的整倍数大大提高了CPU存取数据的性能,参考维基百科关于数据alignment的说明 。 就Hotspot而言,不管是32位系统还是64位系统要求(步骤1 + 步骤2 + padding) % 8等于0且0 <= padding < 8。例如在64位系统上: public class Student { private int age; } 如new Student()则其占用内存: 16 + 4 = 20,按照3中的说明则padding为4bytes,这样整个内存占用为24bytes。 六. 一维原生数组的内存占用 ——————————————————————————————– 1. 在32位的系统中, 占用内存为: 型别占用内存 * 数组长度 + 8(数组在JVM中被当成特殊的对象, object overhead占用8bytes) + 4(数组长度) + padding。如: byte[2], 型别占用内存,即byte型别占用1byte,数组长度为2,这样占用的总内存为1 * 2 + 8 + 4 = 14,padding上2bytes为16bytes,所以byte[2]占用内存为16bytes。 2. 在64位的系统中, 占用内存为: 型别占用内存 * 数组长度 + 16(object overhead占用16bytes) + 8(数组长度) + padding。如: byte[2], 型别占用内存,即byte型别占用1byte,数组长度为2,这样占用的总内存为1 * 2 + 16 + 8 = 26,padding上6bytes,26 + 6 = 32bytes,所以byte[2]占用内存为32bytes 七. 多维数组和一维对象数组 ——————————————————————————————– 1. 在32位的系统中, 占用内存为: reference占用内存 * 数组第1维长度 +12(数组本身被当做reference占8bytes,数组长度占4bytes)。如: byte[3][7], reference占用内存4byte,数组第1维长度为3,这样占用的总内存为4 * 3 + 12 = 24,所以byte[3][7]占用内存为24bytes。再如byte[7][3], reference占用内存4byte,数组第1维长度为7,这样占用的总内存为4 * 7 + 12 = 40,所以byte[7][3]占用内存为40bytes。再如new HashMap[7][6][4],reference占用内存4byte,数组第1维长度为7,这样占用的总内存为4 * 7 + 12 = 40,所以HashMap[7][6][4]占用内存为40bytes。 2. 在64位的系统中, 占用内存为: reference占用内存 * 数组第1维长度 +24(数组本身被当做reference占16bytes,数组长度占8bytes)。如: byte[3][7], reference占用内存8byte,数组第1维长度为3,这样占用的总内存为8 * 3 + 24 = 48,所以byte[3][7]占用内存为48bytes。 八. 编码计算 ——————————————————————————————– 1. java.lang.instrument.Instrumentation实例由JVM产生,我们需实现一个代理(agent),根据java.lang.instrument的package specification说明,这个代理里需有个public static void premain(String agentArgs, Instrumentation inst); 方法,这样在JVM初始化后在调用应用程序main方法前,JVM将调用我们agent里的这个premain方法,这样就注入了Instrumentation实例。 2. 计算实例的内存大小,通过Instrumentation#getObjectSize(Object objectToSize)获得。 3. 注意: 如果有field是常量(如, Boolean.FALSE),因为多实例共享,所以算其占用内存为0。 4. 如计算对象Deep范围内存占用的话则需递归计算引用对象占用的内存,然后进行累加。 5. 代码实现如下MemoryCalculator.java: /* * @(#)MemoryCalculator.java 1.0 2010-11-8 * * Copyright 2010 Richard Chen([email protected]) All Rights Reserved. * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package charpter.memory; import java.lang.instrument.Instrumentation; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.IdentityHashMap; import java.util.Map; import java.util.Stack; /** * 提供实例占用内存大小的计算功能. 内部借助JVM的{@link Instrumentation}实现. * * @author Rich, 2010-11-8. * @version 1.0 * @since 1.0 */ public final class MemoryCalculator { /** * JVM在初始化后在调用应用程序main方法前将调用本方法, 本方法中可以写任何main方法中可写的代码. * * @param agentArgs 命令行传进行来的代理参数, 内部需自行解析. * @param inst JVM注入的句柄. */ public static void premain(String agentArgs, Instrumentation inst) { instrumentation = inst; } /** * 计算实例本身占用的内存大小. 注意: * 1. 多次调用可能结果不一样, 主要跟实例的状态有关 * 2. 实例中成员变量如果是reference类型, 则reference所指向的实例占用内存大小不统计在内 * * @param obj 待计算内存占用大小的实例. * @return 内存占用大小, 单位为byte. */ public static long shallowSizeOf(Object obj) { if (instrumentation == null) { throw new IllegalStateException("Instrumentation initialize failed"); } if (isSharedObj(obj)) { return 0; } return instrumentation.getObjectSize(obj); } /** * 计算实例占用的内存大小, 含其成员变量所引用的实例, 递归计算. * * @param obj 待计算内存占用大小的实例. * @return 内存占用大小, 单位为byte. */ public static long deepSizeOf(Object obj) { Map calculated = new IdentityHashMap(); Stack unCalculated = new Stack(); unCalculated.push(obj); long result = 0; do { result += doSizeOf(unCalculated, calculated); } while (!unCalculated.isEmpty()); return result; } /** * 判断obj是否是共享对象. 有些对象, 如interned Strings, Boolean.FALSE和Integer#valueOf()等. * * @param obj 待判断的对象. * @return true, 是共享对象, 否则返回false. */ private static boolean isSharedObj(Object obj) { if (obj instanceof Comparable) { if (obj instanceof Enum) { return true; } else if (obj instanceof String) { return (obj == ((String) obj).intern()); } else if (obj instanceof Boolean) { return (obj == Boolean.TRUE || obj == Boolean.FALSE); } else if (obj instanceof Integer) { return (obj == Integer.valueOf((Integer) obj)); } else if (obj instanceof Short) { return (obj == Short.valueOf((Short) obj)); } else if (obj instanceof Byte) { return (obj == Byte.valueOf((Byte) obj)); } else if (obj instanceof Long) { return (obj == Long.valueOf((Long) obj)); } else if (obj instanceof Character) { return (obj == Character.valueOf((Character) obj)); } } return false; } /** * 确认是否需计算obj的内存占用, 部分情况下无需计算. * * @param obj 待判断的对象. * @param calculated 已计算过的对象. * @return true, 意指无需计算, 否则返回false. */ private static boolean isEscaped(Object obj, Map calculated) { return obj == null || calculated.containsKey(obj) || isSharedObj(obj); } /** * 计算栈顶对象本身的内存占用. * * @param unCalculated 待计算内存占用的对象栈. * @param calculated 对象图谱中已计算过的对象. * @return 栈顶对象本身的内存占用, 单位为byte. */ private static long doSizeOf(Stack unCalculated, Map calculated) { Object obj = unCalculated.pop(); if (isEscaped(obj, calculated)) { return 0; } Class clazz = obj.getClass(); if (clazz.isArray()) { doArraySizeOf(clazz, obj, unCalculated); } else { while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (!Modifier.isStatic(field.getModifiers()) && !field.getType().isPrimitive()) { field.setAccessible(true); try { unCalculated.add(field.get(obj)); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } } } clazz = clazz.getSuperclass(); } } calculated.put(obj, null); return shallowSizeOf(obj); } /** * 将数组中的所有元素加入到待计算内存占用的栈中, 等待处理. * * @param arrayClazz 数组的型别. * @param array 数组实例. * @param unCalculated 待计算内存占用的对象栈. */ private static void doArraySizeOf(Class arrayClazz, Object array, Stack unCalculated) { if (!arrayClazz.getComponentType().isPrimitive()) { int length = Array.getLength(array); for (int i = 0; i < length; i++) { unCalculated.add(Array.get(array, i)); } } } /** JVM将在启动时通过{@link #premain}初始化此成员变量. */ private static Instrumentation instrumentation = null; } 以上代码请参考: http://www.javaspecialists.eu/archive/Issue142.html。 九. 打包及测试 ——————————————————————————————– 1. 将MemoryCalculator.java编译后打包为javatutorial.jar,修改jar中的META-INF/MANIFEST.MF文件,在文件结尾处添加新的一行Premain-Class: charpter.memory.MemoryCalculator,注意冒号后有一个空格,行尾有回车。 2. 编写测试代码TestMem.java,如下: /* * @(#)TestMem.java 1.0 2010-11-8 * * Copyright 2010 Richard Chen(email: [email protected]) All Rights Reserved. * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package charpter.mem; import java.util.HashMap; import charpter.memory.MemoryCalculator; /** * Java对象内存占用的测试. * * @author Rich, 2010-11-8. * @version 1.0 * @since 1.0 */ public class TestMem { public static void main(String[] args) { long result = MemoryCalculator.shallowSizeOf(new Object()); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[1000]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[2]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[2][3]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[3][3]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[9][3]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[2][3][3]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[7][3]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[3][7]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new byte[7][6][4]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new HashMap[7][6][4]); System.out.println(result); result = MemoryCalculator.shallowSizeOf(new HashMap[7]); System.out.println(result); } } 3. 编译TestMem.java,然后执行之。注意在命令行要指定代理类,即: -javaagent:javatutorial.jar,以下为本人在自己测试环境下的执行结果 a. Linux, 64bits, 64位JDK1.5, 执行命令: java -javaagent:/home/adapp/javatutorial.jar -cp /home/adapp/javatutorial.jar:/home/adapp/ charpter.mem.TestMem 结果输出: 16 1024 32 40 48 96 40 80 48 80 80 80 b. Windows 7, 32bits, 32位JDK1.5, 配置的命令行参数为: -javaagent:D:/Temp/javatutorial.jar,执行结果 8 1016 16 24 24 48 24 40 24 40 40 40 c. Windows 7, 64bits, 32位JDK1.5, 配置的命令行参数为: -javaagent:D:/Temp/javatutorial.jar,执行结果 8 1016 16 24 24 48 24 40 24 40 40 40 d. Windows 7, 64bits, 64位JDK1.7.0_09, 配置的命令行参数为: -javaagent:D:/Temp/javatutorial.jar,执行结果 16 1016 24 24 32 56 24 48 32 48 48 48 从上述输出结果可以看出,案例a, b, c与步骤四至七的理论分析一致。案例d与理论分析不完全一致,但是大小比例关系依然存在,这主要是Hotspot对对象指针采用了压缩算法,由官方资料关于Compressed oops(ordinary object pointer)的说明 可以看出,从Java SE 6u23之后的64位版本就默认打开了对象指针压缩。 十. Compressed oops的内存占用 注意,Compressed oops只在64位的JVM中才会有,另外,在Java SE 6u23之前的1.6版本中需要通过-XX:+UseCompressedOops参数开启。压缩算法对对象内存占用计算的影响主要在于: ——————————————————————————————– 1. object header,未压缩前由一个native-sized mark word 8bytes加上一个class word 8bytes组成,共16bytes。采用压缩后,class word缩减为8bytes,现共占用12bytes; 2. reference类型,由8bytes缩减为4bytes; 3. 数组长度,由8bytes缩减为4bytes。 所以,上述测试案例中: ——————————————————————————————– 1. 原生类型,内存占用大小不变。 2. 对象类型,object header由16bytes变更为12bytes,reference类型的fields由8bytes变更为4bytes,primitive类型的fields保持不变,padding不变。 3. 一维原生数组,如new byte[2]占用内存的计算公式由:型别占用内存 * 数组长度 + 16 + 8 + padding变更为: 型别占用内存 * 数组长度 + 12 + 4 + padding,这样得到: 1byte * 2 + 12 + 4 = 18,padding上6bytes等于24bytes。 4. 多维数组和一维对象数组,如new byte[3][7],计算公式由: reference占用内存 * 数组第1维长度 +24(数组本身被当做reference占16bytes,数组长度占8bytes) 变更为: reference占用内存 * 数组第1维长度 + 16(object header 12bytes,数组长度占4bytes) + padding,这样得到:4bytes * 3 + 16 = 28,padding上4bytes等于32bytes。 再如new HashMap[7],7 * 4bytes + 16 = 44bytes,padding上4bytes为48bytes。 十一. 总结 通过上述Java内存占用大小的理论分析与实际测试,给我们实际开发带来几点重要的启发: ——————————————————————————————– 1. 同样的程序在不同环境下运行,占用的内存不一样大小,64位系统上占用的内存要比在32位系统上多1至1.5倍; 2. n个元素的数组要比n个单独元素占用更大的内存,特别是primitive类型的数组; 3. 定义多维数组时,要尽可能把长度小的放在第1维,即int[9][1]要比int[1][9]占用更多内存,Integer[1000][4][3]远比Integer[3][4][1000]占用的内存要多得多; 4. Java SE 6u23之后的64位版本要比之前的版本在对象内存占用方面小得多。 十二. 参考资源 1. http://www.javamex.com/tutorials/memory/object_memory_usage.shtml 2. https://wikis.oracle.com/display/HotSpotInternals/CompressedOops Continue reading 【转】Java对象占用内存大小的分析与计算 其中 ${project.build.directory}是指当前工程的target目录,运行package则会将所有依赖包拷贝到lib目录下。 参见: http://stackoverflow.com/questions/97640/force-maven2-to-copy-dependencies-into-target-lib Continue reading maven 拷贝所有依赖到指定目录 in Web前端 on javascript 这次遇到个问题,子窗体脚本向父窗体添加了个脚本,但是添加的脚本的上下文却是子窗体!也就是说,在被添加的脚本中操作dom其实是操作的子窗体的dom,window对象也是子窗体的window。 为什么这样我还没找到文档。 类似这样: 子窗体脚本: $(‘head’,parent.document).append(‘<script src=”xxxx.js”></script>’); xxx.js里: log(window); 会发现是子窗体的window对象。 Continue reading 同源跨窗口添加脚本的上下文 in 默认分类 今天试用了一下Evernote, 界面做的不错,国内也没被墙,很想将被兲朝虐的不行Google Drive里的资料导进去,发现居然不可以。PDF,word什么的都不支持。 网上所抱怨的格式兼容什么的确实不假,想想还是算了,难道还一篇篇重写不成,我还那么多图片在文档里。果断删了。 还是凑合着用Google吧,虽然那动不动就“正在联系服务器”的提示让人咬牙切齿,但还是很强大的。 Continue reading Evernote 使用后感 mac osx下要活的当前文件夹路径不是个很方便的事情,因为它没有winows那样的地址栏,那么: 方法一: command+I获得简介,从里面copy路径 这个不好用 方法二: 网上找到的 在launchpad里打开Automator,在实用工具里找到Run AppleScript,选择no input,从左边Run AppleScript拖到右边,就会出现脚本编辑。 拷贝脚本 try 替换(* Your script goes here *) command+save 保存一个名字。 然后你就可以在系统设置、键盘快捷键、通用下 找到你创建的服务,给它一个快捷键,那么在任何文件夹下只要这个快捷键就可以将其拷贝到粘贴板上了。 具体参见: http://apple.stackexchange.com/questions/47216/copying-the-current-directorys-path-to-the-clipboard Continue reading mac osx 拷贝当前文件夹路径 往往导入一个新工程,发现很多语法验证错误,但那本不是错误。看的很烦心,这个问题我以前碰到过,只是没有烂一下笔头,这次又出现了,弄了半天,才发现在problems里点击这些错误,右键删除即可。 Continue reading eclipse 遇到很多验证错误 碰到这样的问题真让人捉急啊,什么线索也没有。只能靠猜测了,尝试多种办法都不行,最后试试网上有没有解决方案,居然有: 将工程下 .setting 和.project文件删除再重新配置即可。 参见: Continue reading eclipse An internal error occurred during: "Updating Maven Project". java.lang.NullPointerException 问题 hostigation.com vps主机使用吐槽
onenote mac 免费版使用
【转】Java对象占用内存大小的分析与计算
maven 拷贝所有依赖到指定目录
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
同源跨窗口添加脚本的上下文
Evernote 使用后感
mac osx 拷贝当前文件夹路径
tell application "Finder" to set the clipboard to POSIX path of (target of window 1 as alias)
on error
beep
end try eclipse 遇到很多验证错误
eclipse An internal error occurred during: "Updating Maven Project". java.lang.NullPointerException 问题