分类 默认分类 下的文章

JVM 常见的启动参数 flags

//jit 编译器类型

  • -client //32位 client, 启动早, 编译不耗时
  • -server //32位 server, 启动晚, 编译耗时, 最终代码更优化,更快
  • -d64 //64位
  • -XX: TieredCompilation //必须使用 server 编译器, 先 client, 再 server 重新编译
  • -XX:InitialCodeCacheSize=N //初始 code cache 值, 可以通过 jconsole 查看
  • -XX:ReservedCodeCacheSize=N //最大 code cache 值
    //编译开始的 threshold, 不是全局累加计数, 而是移动区间计数
  • -XX:PrintComplilation //打印编译日志 可以通过 jstat 查看编译的统计信息或 jconsole
  • -XX:CompileThreshold=N //是否启动编译的 threshold (方法调用计数器 循环回边计数器)
  • -XX:OnStackReplacePercentage=N //OSR 的 threshold 值, 需要通过公式计算次数
  • -XX:CICompilerCount=N //编译器的线程数
  • -XX:Printflagsfinal 启动时打印所有标志 flags;
  • -XX:+Inline //内联 默认是 true
  • -XX:+DoEscapeAnalysis //逃逸分析 默认是 true

//GC refer: https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html

  • -XX:+UseSerialGC
  • -XX:+UseParallelGC
  • -XX:-UseParallelOldGC
  • -XX:+UseConcMarkSweepGC
  • -XX:+UseParNewGC
  • -XX:+UseG1GC

//GC log refer: https://dzone.com/articles/enabling-and-analysing-the-garbage-collection-log

  • -XX:+PrintGC

  • -XX:+PrintGCDetails

  • -XX:+PrintGCTimeStamps

  • -XX:+PrintGCDateStamps

  • -Xloggc:

  • -XX:+PrintGCApplicationStoppedTime

  • -XX:+PrintGCApplicationConcurrentTime

  • -XX:+UseGCLogFileRotation

  • -XX:NumberOfGCLogFiles=5

  • -XX:GCLogFileSize=2000k

  • -XX:ParallelGCThreads=N //并发启动的GC 回收线程数目

  • -XX:+DisableExplicitGC

//heap related

  • -Xms //heap start eg: -Xms3000m
  • -Xmx //heap max eg: -Xmx:4000m
  • -XX:NewRatio=N //新生代和老年代占比用比率, default 2. 新生代大小=总堆大小/(1+NewRatio)
  • -Xns //Nursery Start eg: -Xns800m
  • -XX:NewSize=N //新生代初始大小
  • -XX:MaxNewSize=N //新生代最大值
  • -XX:PermSize=N //永久带初始大小
  • -XX:MaxPermSize=N //永久带最大值
  • -XX:MetaspaceSize=N //java8 元空间初始大小
  • -XX:MaxMetaSpaceSize=N //java8 元空间最大值
  • -XX:+PrintAdaptiveSizePolicy //打印自适应策略相关信息
  • -XX:+UseAdaptiveSizePolicy //使用自适应策略. 若xms,xmn,xns固定死,则不使用

//JFR

  • -XX:UnlockCommercialFeatures
  • -XX:+flightRecorder

官方文档: https://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html#PerformanceTuning

作为服务器运行的 JVM 最好设置下面这些参数:

-Xms<heap size>[g|m|k] 
-Xmx<heap size>[g|m|k]
-XX:MaxMetaspaceSize=<metaspace size>[g|m|k]
-Xmn<young size>[g|m|k]

-Xloggc:"<path to log>"
-XX:+PrintGCDetails 
-XX:+UseGCLogFileRotation 
-XX:NumberOfGCLogFiles=10 
-XX:GCLogFileSize=10M
-XX:+PrintGCDateStamps 

-Dsun.net.inetaddr.ttl=<TTL in seconds>

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=<path to dump>`date`.hprof

MAC 使用 Ctrl C/V 进行复制粘贴

MAC 接了一个 win 键盘, 发现最麻烦的是 Command + C/V 和 Ctrl + C/V 之间的切换.
于是找到了这个方法: 给 win 键盘的 Ctrl + C/V/A/X 作为 Copy/Paste/All/Cut 的快捷键.

https://superuser.com/questions/28078/remap-copy-and-paste-shortcuts-on-a-mac
Go System Preference > Keyboard > keyboard shortcuts and set Application Keyboard Shortcuts > All Applications

Add shortcut
Copy ^C
Undo ^Z
Cut ^X
Paste ^V
Select All ^A

Done :)

严格按照上面的大小写.

Mac 外置机械键盘 定制 command 和 alt 键

Mac键盘和其他键盘最多用的差别是 copy/paste 的时候, 使用 command + C/V, 他的 Command 在空格键旁边. 最近新接了一个外接机械键盘, 可是上面的 win( 也就是 command) 键在 Ctrl 和 alt 中间, 也就是 alt 和 win 键要交换位置才舒服, 于是找到网上这篇文章, mac 可以通过定制控制键来匹配.

https://www.engadget.com/2007/09/13/mac-101-change-keyboard-modifier-keys-with-a-windows-keyboard/

preference -> keyboard -> keyboard -> modifier keys.

javascript 转换字符的数字为字符

今天在做一个当字符输入, 产生事件的时候, 碰到如下代码, 挺有意思:

$("#input").keyup(function(evt){
    console.log(evt.key);
    console.log(String.fromCharCode(evt.key));
    console.log((evt.key).toString(36));
});

第三种最有意思, 是把数字转换为36进制, 1,2,3 ... 8,9,0,a,b,c ... z. 很巧妙啊

Spring AspectJ AOP 和 redirect ModelAndView 导致的内存泄漏问题

今天遇到一个缓慢内存泄漏的问题, 经查, 与 Spring MVC 的 redirect 使用相关.

如果使用了 Spring 的 Spring AspectJ AOP 和 ModelAndView, 并且在 redirect 的时候, 是如下面的跳转, 就可能有缓慢内存泄漏的问题.
当 redirect 时候, redirect 的 URL 是变化的时候, 就会出现内存泄漏, 比如下面的代码:

 String redirectUrl = "id=" + String.valueOf(Math.random());
 return new ModelAndView(String.format("redirect:%s", redirectUrl));

原因是: 在页面解析的时候, 这个 ModelAndView 会被 Spring 重新生成一个 RedirectView, 这个 RedirectView 被 Spring 生成之后, 会执行一个 postProcessAfterInitialization 方法, 如果这时候是使用 AspectJ AOP, 那么 AspectJ 会把生成的一个 bean 放入一个 全局唯一的 ConcurrentHashMap里面, 放的时候以 bean.getClass() + beanName 作为 key. 然而对于 RedirectView, 这个 beanName 正是这个 redirect 的 URL, 如果它是一个变化的值, 那么就会持续添加. 代码:

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

发生添加的Stack trace 如下, 可以进行 debug 验证:
Debug_-<em>org_springframework_web_servlet_DispatcherServlet</em>-<em>RIDE_for_Raptor_2</em>-__Users_xiatian_Documents_workspaceSre.png