Java 垃圾收集器

本文仅针对 JDK 1.8

年轻代垃圾收集器

Serial、ParNew、Parallel Scavenge、Epsilon

老年代垃圾收集器

CMS、Serial Old、Parallel Old

同时支持年轻代、老年代

G1、ZGC(暂不分代)、Shenandoah

没有最好、万能的垃圾收集器,我们需要根据不同的应用场景挑选适合的垃圾收集器。

Read More

Java 垃圾收集算法

分代收集理论

当前虚拟机的垃圾收集都采用分代收集理论,根据对象存活时间不同将内存分为几块。Java推分为新生代和老年代,我们根据各个年龄代不同的特性选择合适的垃圾收集算法。在新生代,每次收集都会有大量的对象(99%)死亡,可以选择复制算法,只需要付出少量对象的复制成本就可以完成垃圾收集。老年代存活率比较高,而且没有额外的空间对它进行分配担保,所以我们必须选择标记-清除或者标记-整理算法。标记清除和标记整理算会会比复制算法慢10倍以上。

Read More

Java对象创建与回收

加载类

我们都知道类的加载过程有加载->验证->准备->解析->初始化几个步骤,才能正式使用,当我们用new指令创建对象时,虚拟机会判断该类是否已经完成加载,如果没有,先执行上述的加载步骤,如果已经完成加载,就开始创建对象。一旦一个类加载完成,待创建对象所需的内存大小就已经确定了,为对象分配空间,等同于把一块确定大小的内存从堆里划分出来。

分配内存

划分内存方法

指针碰撞(Bump the Pointer) (默认)

如果垃圾收集器采用标记整理算法,Java堆中的内存是规整的,所有用过的内存都在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离。

空闲列表(Free List)

如果Java堆中的内存并不是规整的(标记清除算法),已使用的内存和空 闲的内存相互交错,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记 上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录.

Read More

JVM常用参数

  • -xms512m 初始堆大小512M,默认物理内存的1/64
  • -Xmx512m 最大堆大小512M,默认物理内存的1/4

初始内存跟最大内存最好相等,防止内存不够时扩充内 存或者Full GC,导致性能降低

  • -XX:+HeapDumpOnOutofMemoryError 内存异常打印dump
  • -XX:NewSize=100m 新生代初始化内存的大小(需要小于-xmx)
  • -XX:MaxNewSize=100m 是新生代可被分配的内存的最大上限
  • -Xmn100m 新生代内存100m,同时对-XX:MaxNewSize和-XX:NewSize设置,一致可以避免动态调整
  • -XX:NewRatio=2 默认2表示新生代为年老代的1/2,占整个堆内存的1/3。
  • -XX:SurvivorRatio=8 默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。

以上配置可以推出老年代内存512-100=412M

  • -XX:SurvivorRatio=8 新生代内存分配比例(8:1:1,总共10,如果配6,就是6:2:2)
  • -XX:MaxMetaspaceSize=256M 设置元空间最大值, 默认是-1, 即不限制, 或者说只受限于本地内存大小
  • -XX:MaxMetaspaceSize=256M 指定元空间触发Full gc的初始阈值,默认是21M,达到该值就会触发 full gc进行类型卸载, 同时收集器会对该值进行调整: 如果释放了大量的空间, 就适当降低该值; 如果释放了很少的空间, 那么在不超 过-XX:MaxMetaspaceSize(如果设置了的话) 的情况下, 适当提高该值。

如果程序启动慢,观察是否在启动过程中频繁full gc,如果是,可能是程序比较大,因为Metaspace存放类的信息,很快达到了21M,频繁Full gc扩容,可以试着改大。建议MaxMetaspaceSize和MaxMetaspaceSize改成一样

  • ‐Xss1m 设置每个线程的栈大小,默认1M,通常够用,影响一个线程栈里能分配的栈帧数,太小了容易StackOverflowError

JVM优化,就是尽可能让对象都在新生代里分配和回收,尽量别 让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免新生代频繁的进行垃圾回收。没有通用的调优参数,需要根据业务场景来。

博客迁移到Hexo

忍不了wordpress的缓慢,没找到一个完美支持markdown,又看得上的主题,是这次迁移的原因。按官方文档迁移后,现在的效果是文章基本都没问题,但是类目,tag之类的链接全变了,所以会有很多404,但还好,反正博客访问量也不大。静态网站,速度贼快,哈哈。

编辑器,我现在用的是Visual Studio Code,图片用PicGo插件,配上阿里云oss,非常方便。部署用的是hexo-deployer-rsync插件,一条命令,打算写个小脚本,配上gitlab runner,实现提交后自动部署。

Spring cloud使用zookeeper作为分布式配置中心

为什么要用配置中心

Spring boot项目在启动时会加载application.properties(或yaml)里的配置,如果修改了application.properties,需要重新打包、部署,当服务有多个实例,需要每个都重新部署。配置中心就是用来解决这个问题的,我们所配置内容放在配置中心统一管理,项目启动时先去配置中心拉取配置,再用这些配置执行启动操作。如果配置有变更,在配置中心修改后,只需要一一重启服务,即可完成配置更新。有些配置中心甚至不需要重启,支持配置推送,比如我们今天介绍的Spring cloud zookeeper config。

Spring Cloud Zookeeper Config 介绍

Zookeeper提供了一个类似目录树的存储结构,允许客户端存储任意数据,如:配置数据。

Spring Cloud Zookeeper Config是Spring Cloud Config Server和Client的替代方案(这个方案需要起一个server服务,依赖git存储配置),在bootstrap阶段,加载配置到Spring环境中。

默认情况下,配置存储在/config节点下。Spring Cloud Zookeeper Config会基于应用程序名称和profile创建多个PropertySource模拟Spring Cloud Config顺序从Zookeeper读取并解析配置。

例如,应用名是testApp,profile是dev会创建下面几个property源:

1
2
3
4
/config/testApp,dev
/config/testApp
/config/application,dev
/config/application

配置优先级是从上至下的。/config/application 会应用到所有使用zookeeper作配置中心的项目上,/config/testApp 只对应用名为testApp的项目有效.

Read More

Kong http 301跳转到https插件

安全起见,我们希望用户使用https协议访问网站,但是在不输协议的时候,浏览器默认使用的是http协议。如果之前使用的是http协议,搜索引擎也会索引http协议的链接,用户点击打开的也是http协议。 出于对搜索引擎友好起见,这种场景我们一般使用301重定向,告诉搜索引擎已经永久转移到一个新地址,以后索引新地址。 之前我的博客一直存在这个问题,前端用kong,处理wordpress加了个nginx,kong和nginx之间http协议通讯。之前没有kong的时候,在nginx上配置重定向所有http到https,但是加了kong,不能这么做了,因为不管用户访问kong用的是http还是https,到nginx都是http。 今天抽了点时间写了个kong插件,完美解决这个问题,欢迎fork kong-plugin-http301https

Kong网关可视化管理界面 kong admin ui

这段时间在学习kong,用postman或是curl操作kong admin api始终不太方便.有个开源项目叫kong dashboard,但貌似不支持最新版的kong。 于是自己用Vue和iView写了一个简单的管理界面,目前只支持Service,Route,Upstream,Target的增删改查,后续会添加更多功能。项目已托管到github: https://github.com/pocketdigi/kong-admin-ui 纯前端项目,所有对Kong admin api的操作都是浏览器发出的,所以,要求您的网络环境可以直接访问kong admin api。这么设计是想方便大家,不用再单独部署一套Kong的UI,如果你只是想找个管理界面,不想对这个项目进行二次开发,那么,只需要使用我部署的 demo。除了你的kong admin api接口,不会再请求其他接口,所以你可以放心,我不会保存你的任何信息。