JVM日志管理统计Runtime中freeMemory,totalMemory,maxMemory
1、导入log4j.jar包
2、在src源码包下建立log4j.properties配置文件
log4j.peoperties
log4j.rootLogger=INFO,Console,RollingFile,RollingFileWarn #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.Threshold=INFO log4j.appender.Console.layout.ConversionPattern=%d %-5p [%c{5}] - %m%n #RollingFile log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFile.DatePattern='.'yyyy-MM-dd log4j.appender.RollingFile.File=G://logs/log.log log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n #RollingFile Warn log4j.appender.RollingFileWarn=org.apache.log4j.DailyRollingFileAppender log4j.appender.RollingFileWarn.DatePattern='.'yyyy-MM-dd log4j.appender.RollingFileWarn.File=G://logs/logwarn.log log4j.appender.RollingFileWarn.layout=org.apache.log4j.PatternLayout log4j.appender.RollingFileWarn.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n log4j.appender.RollingFileWarn.Append=true log4j.appender.RollingFileWarn.Threshold=WARN #loginCtrl登录时写入日志,级别设置为warn log4j.logger.com.ctrl.loginCtrl=WARN
3、spring-mvc.xml
<!--配置拦截器, 多个拦截器,顺序执行 --> <mvc:interceptors> <mvc:interceptor> <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller --> <mvc:mapping path="/goindex.do" /> <bean class="com.frame.interceptor.CommonInterceptor"></bean> </mvc:interceptor> <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 --> </mvc:interceptors>
4、CommonInterceptor.java
package com.frame.interceptor; import java.text.SimpleDateFormat; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.core.NamedThreadLocal; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class CommonInterceptor extends HandlerInterceptorAdapter{ private final Logger log = Logger.getLogger(CommonInterceptor.class); private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long beginTime = System.currentTimeMillis();//1、开始时间 startTimeThreadLocal.set(beginTime); //线程绑定变量(该数据只有当前请求的线程可见) log.warn("开始计时:"+new SimpleDateFormat("hh:mm:ss.SSS") .format(beginTime)+" URI:"+request.getRequestURI()); Thread.currentThread().sleep(3000); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 打印JVM信息。 long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间) long endTime = System.currentTimeMillis(); //2、结束时间 log.warn("计时结束:{"+new SimpleDateFormat("hh:mm:ss.SSS").format(endTime)+"} 耗时:{"+formatDateTime(endTime - beginTime)+"} URI: {"+request.getRequestURI()+"} 最大内存: {"+Runtime.getRuntime().maxMemory()/1024/1024+"}m 已分配内存: {"+Runtime.getRuntime().totalMemory()/1024/1024+"}m 已分配内存中的剩余空间: {"+Runtime.getRuntime().freeMemory()/1024/1024+"}m 最大可用内存: {"+(Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024+"}m"); } /** * 转换为时间(天,时:分:秒.毫秒) * @param timeMillis * @return */ public static String formatDateTime(long timeMillis){ long day = timeMillis/(24*60*60*1000); long hour = (timeMillis/(60*60*1000)-day*24); long min = ((timeMillis/(60*1000))-day*24*60-hour*60); long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60); long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000); return (day>0?day+"天"+",":"")+(hour>0?hour+"小时"+",":"")+(min>0?min+"分钟"+",":"")+s+"."+sss+"秒"; } }
对应日志输出
maxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操作系统那里挖到的最大的内存。如果添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。
totalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有 内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖- Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。
freeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程 序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可
能会有些大。