0%

文章字数:236,阅读全文大约需要1分钟

常用规则

NO 关键词 实例 sql
1 And findByNameAndAge where name=?1 and age=?2
2 Or findByLastnameOrFirstname where lastname=?1 or firstname=2?
3 Is,Equals findByFirstnameIs;等于findByFirstname where name=?1
4 Between findByStartDateBetween where startDate between ?1 and ?2
5 LessThan findByAgeLessThan where age < ?1
6 LessThanEqual findByAgeLessThanEqual where age<= ?1
7 GreaterThan findByAgeGreaterThan where age >?1
8 GreaterThanEqual findByAgeGreaterThanEqual where age >= ?1
9 After findByStartDateAfter where startDate > ?1
10 Before findByStartDateBefore where startDate < ?1
11 IsNull findByAgeIsNull where age is null
12 IsNotNull/NotNull findByAge(Is)NotNull where age not null
13 Like findByFirstnameLike where firstname like ?1
14 NotLike findByFirstnameNotLike where firstname not like ?1
15 StartingWith findByFirstnameStartingWith where firstname like ?1(参数前加上%)
16 EndingWith findByFirstnameEndingWith where firstname like ?1(参数后加%)
17 Containing findByFirstnameContaining where first like ?1(参数前后%)
18 OrderBy findByAgeOrderByLastNameDesc where age = ?1 order by lastname desc
19 Not findByLastnameNot where lastname != ?1
20 In findByAgeIn(Collection ages) where age in ?1
21 NotIn findByAgeNotIn(Collection age) where age not in ?1
22 TRUE findByActiveTrue() where active = true
23 FALSE findByActiveFalse() where active=false
24 IgnoreCase(忽略大小写) findByFirsrnameIgnoreCase where UPPER(firstname) = UPPER(?1)//转为大写
25 existsBy existsByUserId(long userId) where exists(..where userid=?1)

排序分页

方法最后一个参数是Sort或者Pageable会提取信息进行排序或分页

1
2
3
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
public Page findAll(new PageRequest(pageNo,pageSize))
  • 排序
    1
    2
    3
    List<Cus> findBySexOrderByName(String sex); //名称正序(正序时,推荐此方式,简单)
    List<Cus> findBySexOrderByNameAsc(String sex); //名称正序(效果同上)
    List<Cus> findBySexOrderByNameDesc(String sex); //名称倒序
  • 条数限制
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Resource findFirstByFather_idOrderByOrderNumDesc(Long fatherId);

    User findFirstByOrderByLastnameAsc();

    User findTopByOrderByAgeDesc();

    Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);

    Slice<User> findTop3ByLastname(String lastname, Pageable pageable);

    List<User> findFirst10ByLastname(String lastname, Sort sort);

    List<User> findTop10ByLastname(String lastname, Pageable pageable);
  • 计数
    1
    Long countByLastname(String lastname);
  • 删除
    1
    2
    void deleteByProject_Id(Long id);
    void deleteByProject_Cus_id(Long id);

文章字数:515,阅读全文大约需要2分钟

jquery.validate.min.js 是一款基于jq的表单验证工具。找到的教程大部分都是同步提交下的使用,以下是我找到的ajax提交方式下的使用。

使用内置验证规则

  1. 为表单添加表单验证

    1
    $("#cForm").validate();

    表单验证错误信息输出位置自定义

    1
    2
    3
    4
    <!-- input是表单的输入框 -->
    <div class="inputMain">用户名:<input type="text" name="user" /></div>
    <!-- for和input的name绑定 -->
    <div style="height:20px;"><label id="user-error" class="error" for="user"></label></div>
  2. 添加规则

    1
    $("#cForm input[name='name']").rules("add",{required: true}) //规则的意思是必填

3.ajax前验证

1
2
3
if($("#categoryForm").valid()){//验证并返回结果
//ajax...
}

规则和验证信息自定义可以自己百度,信息不写会有默认规则。

附较为详细的规则及自定义提示信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$().ready(function() {
// 在键盘按下并释放及提交后验证提交表单
$("#signupForm").validate({
rules: {
firstname: "required",
lastname: "required",
username: {
required: true,
minlength: 2
},
password: {
required: true,
minlength: 5
},
confirm_password: {
required: true,
minlength: 5,
equalTo: "#password"
},
email: {
required: true,
email: true
},
topic: {
required: "#newsletter:checked",
minlength: 2
},
agree: "required"
},
messages: {
firstname: "请输入您的名字",
lastname: "请输入您的姓氏",
username: {
required: "请输入用户名",
minlength: "用户名必需由两个字母组成"
},
password: {
required: "请输入密码",
minlength: "密码长度不能小于 5 个字母"
},
confirm_password: {
required: "请输入密码",
minlength: "密码长度不能小于 5 个字母",
equalTo: "两次密码输入不一致"
},
email: "请输入一个正确的邮箱",
agree: "请接受我们的声明",
topic: "请选择两个主题"
}
})
});

自定义验证规则

其他操作参考上面

  1. 添加规则
    1
    2
    3
    4
    5
    jQuery.validator.addMethod("validName", function(value, element){
    var obValue=value;//对象的值
    var ob=element;//需要处理的对象
    return true;
    }, "提示信息");

2.为表单元素添加规则

1
2
3
$("#nameInput").rules("add",{
validName:true; //规则名:期望值(未达到期望值提示自定义的错误信息)
});

3.传参

1
2
3
4
5
6
7
8
9
10
$.validator.addMethod("af",function(value,element,params){  
if(value.length>1){
return false;
}
if(value>=params[0] && value<=params[1]){
return true;
}else{
return false;
}
},"必须是一个字母,且a-f");
1
2
3
username:{
af:["a","f"]
}

其它方式提交表单

1
2
3
4
5
6
$(".selector").validate({     
submitHandler: function(form)
{
$(form).ajaxSubmit();
}
})

其他功能

  1. 只验证不提交

    1
    2
    3
    4
    5
    6
    $().ready(function() {
    //只验证不提交
    $("#signupForm").validate({
    debug:true
    });
    });
  2. 默认参数

    1
    2
    3
    4
    //设置默认参数,使用其它方式提交
    $.validator.setDefaults({
    submitHandler: function(form) { alert("提交事件!");form.submit(); }
    });
  3. 错误显示位置

    1
    2
    3
    4
    //默认是追加到元素后面
    errorPlacement: function(error, element) {
    error.appendTo(element.parent());
    }
  4. 远程校验

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    remote: {
    url: "check-email.php", //后台处理程序
    type: "post", //数据发送方式
    dataType: "json", //接受数据格式
    data: { //要传递的数据
    username: function() {
    return $("#username").val();
    }
    }
    }

文章字数:331,阅读全文大约需要1分钟

对数据库进行操作的时候有时需要加锁,数据库操作往往是线程操作的重合部分。jpa提供了对于数据库锁的支持

@Version

jpa提供的乐观锁,指定实体的字段/属性作为乐观锁的version。每次insertupdate操作都会带上version,进行CAS操作。

  • 字段支持类型:int, Integer, short, Short, long, Long, java.sql.Timestamp
  • 失败会抛出异常org.springframework.orm.ObjectOptimisticLockingFailureException
    需要自己处理异常
  • 具体代码
1
2
3
4
5
6
7
8
9
10
public class user{
@Column
private String name;

/**
* 乐观锁version
*/
@Version
private Integer version;
}

@Lock

  • @Lock注解只有一个value的属性,是LockModeType的枚举类型
1
2
3
4
public interface AccountRepository extends JpaRepositoryImplementation<Account,Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Account findByAccountName(String accountName);
}

锁类型

  1. LockModeType.Optimistic乐观锁,默认的锁类型。事务提交时检查版本
  2. LockModeType.OPTIMISTIC_FORCE_INCREMENT乐观锁,无论实体有没有改变都会累加版本。(这样保证读也是原子性的)
  3. LockModeType.PESSIMISTIC_READ悲观锁,当事务锁住实体时禁止再次写入。允许其他事务使用PESSIMISTIC_READ加锁
  4. LockModeType.PESSIMISTIC_WRITE悲观锁,READ的增强版,数据库禁止读取。
  5. LockModeType.PESSIMISTIC_FORCE_INCREMENT:悲观锁+乐观锁,乐观锁获取和比对之间如果有悲观锁加了锁,因为悲观锁不能更改版本号,所以无法阻止乐观锁覆盖其事务。此锁就是会增加版本号的悲观锁。

文章字数:73,阅读全文大约需要1分钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* content base64格式数据
* fileName 文件名
*/
function downloadFile(content, fileName) {
var base64ToBlob = function(code) {
let parts = code.split(';base64,');
let contentType = parts[0].split(':')[1];
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for(let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {
type: contentType
});
};
let aLink = document.createElement('a');
let blob = base64ToBlob(content); //new Blob([content]);
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.click();
};

文章字数:1775,阅读全文大约需要7分钟

绑定方法

  1. dom.addEventListener("click",func,false);
    对dom对象绑定事件,用func函数处理事件,false代表组织冒泡

  2. dom.removeEventListener("click", myFunction);移除

1
2
3
4
5
passwordOb.addEventListener("keyup",checkFun,false);
//处理事件的函数
function checkFun(e){
console.log("元素:"+e.target+"触发了事件");
}

事件

鼠标事件

属性名 描述
onclick 点击对象触发
oncontextmenu 点击右键打开上下文菜单世触发
ondblclick 双击对象触发
onmousedown 鼠标按钮按下
onmouseenter 鼠标指针移动到元素上(事件不支持冒泡)
onmouseleave 鼠标指针移出元素(事件不支持冒泡)
onmousemove 元素上的指针移动时触发
onmouseover 鼠标移到元素上(事件支持冒泡)
onmouseout 鼠标从元素上移开(事件支持冒泡)
onmouseup 鼠标按键松开

键盘事件

属性名 描述
onkeydown 某个键盘按键被按下
onkeypress 键盘按键被按下并松开
onkeyup 按键被松开

对象事件

属性名 描述
onabort 图像的加载被打断
onbeforeunload 即将离开页面(刷新或关闭)时触发
onerror 加载文档或图像失败时触发
onhashchange 当该事件在当前的URL的锚部分发生修改时触发
onload 一张页面或者图像完成加载
onpageshow 用户访问页面触发(离开后)
onpagehide 当用户离开当前网页跳转到另一个页面触发
onresize 窗口或框架被调整大小
onscroll 文档被滚动时发生
onunload 用户退出页面(beforeunload->unload->pagehide)

表单事件

属性名 描述
onblur 元素失去焦点
onchange 表单内容改变
onfocus 获取焦点
onfocusin 即将获取焦点触发
onfocusout 即将失去焦点触发
oninput 元素获取用户输入时触发
onreset 表单重置时触发
onsearch 用户向搜索域输入文本
onselect 选取文本时触发(选中一小段文字)
onsubmit 表单提交

剪贴板事件

属性名 描述
oncopy 用户拷贝元素内容时触发
oncut 剪切元素时触发
onpaste 用户粘贴元素内容时触发

打印事件

属性名 描述
onafterprint 页面已经开始打印,或者打印窗口已经关闭时触发
onbeforeprint 页面即将开始打印时触发

拖动事件

属性名 描述
ondrag 元素正在拖动时触发
ondragend 元素完成拖动时
ondragenter 拖动元素放入放置目标时
ondragleave 事件在拖动元素离开放置目标时触发
ondragover 元素放置在目标上触发
ondragstart 用户开始拖动元素
ondrop 拖动元素放置在目标区域时触发

多媒体

属性名 描述
onabort 视频、音频终止时触发
oncanplay 用户可以开始播放视频、音频时触发
oncanplaythrough 视频、音频可以正常播放,不用停顿和缓冲时触发
ondurationchange 事件在视频、音频时长发生变化时触发
onemptied 播放列表为空时触发
onended 视频、音频播放结束时触发
onerror 视频、音频数据加载期间发生错误
onloadeddata 浏览器加载视频、音频时当前帧时触发
onloadedmetadata 指定的视频、音频元数据加载后触发
onloadstart 浏览器开始勋在指定视频、音频时触发
onpause 视频、音频暂停时触发
onplay 视频、音频开始时触发
onplaying 视频、音频暂停或者在缓冲后准备重新开始时触发
onprogress 浏览器下载指定视频、音频时触发
onratechange 视频、音频播放速度发生改变时触发
onseeked 重新定位视频、音频时触发
onseeking 重新定位视频、音频时触发
onstalled 浏览器获取媒体数据,但是媒体数据不可用时触发
onsuspend 浏览器读取媒体数据终止时触发
ontimeupdate 当前播放位置发送改变时触发
onvolumechange 当音量发送改变时触发
onwaiting 视频由于要播放下一帧而需要缓存时触发

动画事件

属性名 描述
animationend css动画结束播放时
animationiteration css动画重复播放时
animationstart css动画开始播放时触发

过度事件

属性名 描述
transitionend css完成过度后触发

其它事件

属性名 描述
onmessage 从对象接收到消息时触发(如websocket)
ononline 浏览器开始在线工作时触发
onoffiline 浏览器开始离线工作时触发
onpopstate 浏览历史发生改变时触发
onshow 元素在上下文菜单显示时触发
onstorage web strage更新时触发
ontoggle 打开或关闭
元素时触发
onwheel 鼠标滚轮在元素上上下滚动时触发

事件对象

属性

属性名 描述
bubbles boolean 事件是否是起泡事件
cancelable boolean 事件是否可取消默认动作
currentTarget 返回事件触发器监听的元素
eventPhase 事件传播的当前阶段
target 触发此时间的元素
timeStamp 时间生成的时间和日期
type 当前Event对象表示的时间的名称

方法

方法名 描述
initEvent() 初始化新创建的Event对象的属性
preventDefault() 通知浏览器不要执行事件关联的默认动作
stopPropagation() 不再派发事件

其它方法

方法名 描述
handleEvent() 把任意对象注册成为事件处理程序
createEvent() 该方法将创建一种新的事件类型,该类型由参数 eventType 指定

键盘鼠标对象属性

属性名 描述
altKey 事件触发时,alt是否被按下
button 那个鼠标按钮被点击
clientX 鼠标指针水平位置(浏览器内容区域的左上角,页面滚动参照点会变)
clientY 鼠标指针纯质坐标
Location 按键在设备上的位置
charCode onkeypress事件触发按键值的字母代码
key 按下按键时返回按键的标识符
keyCode 键盘字符代码
which 键盘字符代码
metaKey meta按键是否被按下
relatedTarget 与事件的目标节点相关的节点
screenX 触发事件的水平位置,以显示器作为参照点
screenY 垂直左边
shiftKey shift按钮是否被按下

(pageX参照内容区域左上角,不会随滚动而变化)

initMouseEvent()// 初始化鼠标事件对象的值
initKeyboardEvent()// 初始化键盘事件对象的值


文章字数:370,阅读全文大约需要1分钟

AES对称加密安全性好,加密速度快。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {

/** key长度 */
private static final int KEY_SIZE = 256;
/** 算法名 */
private static final String KEY_ALGORITHM = "AES";
/** 默认的加密算法及模式 */
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";

/**
* AES 加密操作
*
* @param byteContent
* 待加密内容
* @param key
* 加密密钥
* @return 加密数据
*/
public static byte[] encrypt(byte[] byteContent, byte[] key) {
try {
// 创建密码器
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
// 初始化为加密模式的密码器
cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(key));
// 加密
return cipher.doFinal(byteContent);
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

/**
* AES 加密操作,返回Base64字符串
*
* @param byteContent
* 待加密内容
* @param key
* 加密密钥
* @return Base64转码后的加密数据
*/
public static String base64Encrypt(byte[] byteContent, byte[] key) {
byte[] encrypt = encrypt(byteContent, key);
if (encrypt != null) {
return Base64.getEncoder().encodeToString(encrypt);
}
return null;
}

/**
* AES 解密操作
*
* @param content
* 密文
* @param key
* 秘钥
* @return 解密后的数据
*/
public static byte[] decrypt(byte[] content, byte[] key) {
try {
// 实例化
Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
// 使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key));
// 执行操作
return cipher.doFinal(content);
} catch (Exception ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

/**
* AES 解密操作
*
* @param content
* base64形式的密文
* @param key
* 秘钥
* @return 解密后的数据
*/
public static byte[] decrypt(String content, byte[] key) {
if (content != null) {
byte[] decode = Base64.getDecoder().decode(content);
return decrypt(decode, key);
}
return null;
}

/**
* 生成加密秘钥
*
* @return 生成指定算法密钥生成器的 KeyGenerator 对象
*/
private static SecretKeySpec getSecretKey(final byte[] key) {
KeyGenerator kg;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
kg.init(KEY_SIZE, new SecureRandom(key));
// 生成一个密钥
SecretKey secretKey = kg.generateKey();
// 转换为AES专用密钥
return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(AESUtil.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}

public static void main(String[] args) {
String content = "123在下面的文本框内输入需要处理abc";
String key = "个8ga10bg105*()_^%fag1啥干-0人48时阿嘎多沟沟壑壑ssssdca";
System.out.println("原文:" + content);
String s1 = AESUtil.base64Encrypt(content.getBytes(StandardCharsets.UTF_8), key.getBytes());
System.out.println("密文:" + s1);
System.out.println("解密:" + new String(AESUtil.decrypt(s1, key.getBytes()), StandardCharsets.UTF_8));
}
}

文章字数:432,阅读全文大约需要1分钟

在页面加载完成之后我们通常要进行一下初始化js操作,比如根据默认选项调整界面,检测驱动等。除了直接在js里调用函数外,还有几种方式指定函数运行时机。

一、ready()和onload()

  • jqueryready()方法
1
$(document).ready(function(){...})
  • javascriptonload()方法
1
window.onload()=function(){...}

以下是对比:
\ | windo.onload() |$(document).ready
—|—|—
加载时机|图片等信息全部加载完成之后|Dom结构加载之后,不用等图片
执行次数|文件中有多个此函数,最后一个覆盖所有|按顺序执行
简写|无|$(function(){})

二、立即执行函数

创建完函数后立刻执行,和直接调用差不多。。。

1
2
3
(function(){
..
})()

三、js定时,延时

这两个应该不算是初始化,延时执行在特定情况下倒是可以用作初始化。比如初始化操作的节点可能是ajax返回的…好吧,不过他们确实算是让函数在特定时间执行。

  • 定时(多次)
    1
    2
    3
    4
    5
    6
    7
    //函数体,时间
    setInterval("alert('test')",2000);
    //传入函数体
    setInterval(function(){ alert("Hello"); }, 3000);
    //清除定时
    var myVar = setInterval(function(){ myTimer() }, 1000);
    clearInterval(myVar);
  • 延时(一次)
    1
    2
    3
    setTimeout(function(){ alert("Hello"); }, 3000);
    //其它传参方式
    setTimeout(function, milliseconds, param1, param2, ...)

文章字数:225,阅读全文大约需要1分钟

MQTT是一个基于发布/订阅模式的消息协议,专门为硬件性能低下且网络状况糟糕情况设计的。消息轻量级,可以根据设置保证消息一定到达。实现MQTT的中间件有很多,本文采用activeMQ

环境

  1. 页面引入mqttws31.min.js即可
  2. 下载并开启activeMQ,设置好MQTT

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 1. 创建连接
var mqttHost = "127.0.0.1"; // mqtt服务地址
var port = 8083;
var clientId = "test123";
client = new Paho.MQTT.Client(mqttHost, port , clientId );
client.connect({
//连接服务器并注册连接成功处理事件
onSuccess: onConnect,
cleanSession:false,
useSSL:false,
// 心跳
keepAliveInterval:200,
timeout:5,
//userName:"ss",
//password:"xxx",
});
// 连接成功就订阅主题
function onConnect() {
//订阅主题
client.subscribe("topic-name");
}

client.onConnectionLost = function (responseObject) {
if(responseObject.errorCode !== 0) {
console.log("连接已断开");
}
}

client.onMessageArrived = function (message) {
var ss = message.destinationName;
var meg = message.payloadString;
console.log("收到新消息:" + meg);
}

// 推送信息给指定主题
function sendMess(messStr) {
if(client.isConnected()){
var message = new Paho.MQTT.Message(messStr);
// 推送给主题
message.destinationName = "topic-name1";
client.send(message);
}
}

文章字数:5,阅读全文大约需要1分钟

1
2
3
4
5
6
function User(name){
this.name=name;
this.type="people";
}

var user = new User("zhangsan");

文章字数:482,阅读全文大约需要1分钟

内存区域

-Xss

-Xms最小值
-Xmx最大值
-Xmn新生代最小
-XX:newSize新生代最小值
-XX:MaxNewSize新生代最大值

永久代(元空间)

-XX:PermSize -XX:MaxPermsize1.7及之前最小值和最大值
-XX:MetaspaceSize -XX:MaxMetaspaceSize1.8及之后
方法区移动至运行时常量池之外,即元空间

直接内存

  • 不是虚拟机运行时数据区的一部分,也不是java虚拟机规范定义的内存区域
  • NIO中会频繁使用这块区域,java堆内可以使用directByteBuffer对象直接引用操作
  • 此区域不受java堆大小限制,但也受本机总内存限制,可以通过MaxDirectMemorySize设置,默认和堆内存最大值一样,所有也会OOM
1
ByteBuffer b = ByteBuffer.allocateDirect(1024 * 14);

逃逸分析

-server使用server模式运行(只有这个有逃逸分析),还有client模式,mix表示自动判断
-Xmx10M -Xms10m堆大小
-XX+PrintGC打印GC日志
-XX:-EliminateAllocations标量替换
-XX:-UseTLAB事先为每个线程分配一个私有空间ThreadLocalAllocBuffer,可以避免线程new对象时使用同一区域而加锁导致串行