当你应用程序通过RMI发布消息或消费服务时,JVM会定期启动Full GC,确保本地未使用的对象也不会占用内存空间,即使没有在代码逻辑当中添加任何基于JMI的内容,第三方库或工具类仍然可以打开RMI端点(常见的就是JMX),如果远程连接到它,它就会使用RMI在底层发布数据。
RMI造成的问题通常是Old Generation剩有大量空间,但是会触发Full GC,造成stop-the-world。
删除远程引用对象的行为是通过System.gc()触发的,调用System.gc()在sun.rmi.transport.ObjectTable类中调用“sun.misc.GC.requestLatency(long)”方法,不需要设置当前线程类上下文类加载器(ClassLoader = Thread.currentThread().getContextClassLoader(); TCCL),会创建守护线程进行定期的垃圾回收。
Tomcat中JreMemoryLeakPreventionListener的类将“sun.misc.GC.requestLatency(long)”参数设置成了Long.valueOf(Long.MAX_VALUE - 1)。
对于RMI需要定期Full GC的优化,不是必须的,要禁用这种周期性的GC运行,你可以设置以下内容:
java -Dsun.rmi.dgc.server.gcInterval=9223372036854775807L -Dsun.rmi.dgc.client.gcInterval=922337203685477580