本文目录导读:

我来提供一个完整的Java JVM监控实现案例,包含内存、线程、GC等多个维度的监控。
核心监控类
JVMMonitor.java
import java.lang.management.*;
import java.util.*;
import javax.management.*;
import com.sun.management.OperatingSystemMXBean;
public class JVMMonitor {
// 内存监控
public static Map<String, Object> getMemoryInfo() {
Map<String, Object> memoryInfo = new HashMap<>();
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
// 堆内存
MemoryUsage heapMemory = memoryMXBean.getHeapMemoryUsage();
memoryInfo.put("heapInit", heapMemory.getInit());
memoryInfo.put("heapMax", heapMemory.getMax());
memoryInfo.put("heapUsed", heapMemory.getUsed());
memoryInfo.put("heapCommitted", heapMemory.getCommitted());
// 非堆内存
MemoryUsage nonHeapMemory = memoryMXBean.getNonHeapMemoryUsage();
memoryInfo.put("nonHeapInit", nonHeapMemory.getInit());
memoryInfo.put("nonHeapMax", nonHeapMemory.getMax());
memoryInfo.put("nonHeapUsed", nonHeapMemory.getUsed());
memoryInfo.put("nonHeapCommitted", nonHeapMemory.getCommitted());
// 内存池详情
List<Map<String, Object>> memoryPools = new ArrayList<>();
for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
Map<String, Object> poolInfo = new HashMap<>();
poolInfo.put("name", pool.getName());
poolInfo.put("type", pool.getType().toString());
poolInfo.put("usage", pool.getUsage());
poolInfo.put("peakUsage", pool.getPeakUsage());
memoryPools.add(poolInfo);
}
memoryInfo.put("memoryPools", memoryPools);
return memoryInfo;
}
// 线程监控
public static Map<String, Object> getThreadInfo() {
Map<String, Object> threadInfo = new HashMap<>();
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
threadInfo.put("threadCount", threadMXBean.getThreadCount());
threadInfo.put("peakThreadCount", threadMXBean.getPeakThreadCount());
threadInfo.put("totalStartedThreadCount", threadMXBean.getTotalStartedThreadCount());
threadInfo.put("daemonThreadCount", threadMXBean.getDaemonThreadCount());
// 死锁检测
long[] deadlockedThreads = threadMXBean.findDeadlockedThreads();
threadInfo.put("deadlockedThreads", deadlockedThreads != null ? deadlockedThreads.length : 0);
// 线程详情
List<Map<String, Object>> threads = new ArrayList<>();
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
Map<String, Object> thread = new HashMap<>();
thread.put("threadId", info.getThreadId());
thread.put("threadName", info.getThreadName());
thread.put("threadState", info.getThreadState().toString());
thread.put("blockedCount", info.getBlockedCount());
thread.put("blockedTime", info.getBlockedTime());
thread.put("waitedCount", info.getWaitedCount());
thread.put("waitedTime", info.getWaitedTime());
// 堆栈信息
StackTraceElement[] stackTrace = info.getStackTrace();
thread.put("stackTraceLength", stackTrace.length);
threads.add(thread);
}
threadInfo.put("threads", threads);
return threadInfo;
}
// GC监控
public static Map<String, Object> getGCInfo() {
Map<String, Object> gcInfo = new HashMap<>();
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
long totalGcCount = 0;
long totalGcTime = 0;
List<Map<String, Object>> gcDetails = new ArrayList<>();
for (GarbageCollectorMXBean gc : gcBeans) {
Map<String, Object> gcDetail = new HashMap<>();
long count = gc.getCollectionCount();
long time = gc.getCollectionTime();
gcDetail.put("name", gc.getName());
gcDetail.put("collectionCount", count);
gcDetail.put("collectionTime", time);
// GC内存池
String[] poolNames = gc.getMemoryPoolNames();
gcDetail.put("memoryPools", Arrays.toString(poolNames));
gcDetails.add(gcDetail);
totalGcCount += count;
totalGcTime += time;
}
gcInfo.put("totalGcCount", totalGcCount);
gcInfo.put("totalGcTime", totalGcTime);
gcInfo.put("gcDetails", gcDetails);
return gcInfo;
}
// 类加载监控
public static Map<String, Object> getClassLoadingInfo() {
Map<String, Object> classInfo = new HashMap<>();
ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
classInfo.put("loadedClassCount", classLoadingMXBean.getLoadedClassCount());
classInfo.put("totalLoadedClassCount", classLoadingMXBean.getTotalLoadedClassCount());
classInfo.put("unloadedClassCount", classLoadingMXBean.getUnloadedClassCount());
return classInfo;
}
// 系统信息
public static Map<String, Object> getSystemInfo() {
Map<String, Object> systemInfo = new HashMap<>();
OperatingSystemMXBean osMXBean =
(OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
systemInfo.put("osName", System.getProperty("os.name"));
systemInfo.put("osVersion", System.getProperty("os.version"));
systemInfo.put("osArch", System.getProperty("os.arch"));
systemInfo.put("availableProcessors", osMXBean.getAvailableProcessors());
systemInfo.put("systemLoadAverage", osMXBean.getSystemLoadAverage());
systemInfo.put("cpuUsage", osMXBean.getSystemCpuLoad() * 100);
systemInfo.put("processCpuUsage", osMXBean.getProcessCpuLoad() * 100);
systemInfo.put("totalPhysicalMemory", osMXBean.getTotalPhysicalMemorySize());
systemInfo.put("freePhysicalMemory", osMXBean.getFreePhysicalMemorySize());
systemInfo.put("totalSwapSpace", osMXBean.getTotalSwapSpaceSize());
systemInfo.put("freeSwapSpace", osMXBean.getFreeSwapSpaceSize());
return systemInfo;
}
// 编译监控
public static Map<String, Object> getCompilationInfo() {
Map<String, Object> compileInfo = new HashMap<>();
if (ManagementFactory.getCompilationMXBean() != null) {
CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();
compileInfo.put("compilationTime", compilationMXBean.getTotalCompilationTime());
compileInfo.put("compilerName", compilationMXBean.getName());
}
return compileInfo;
}
// 获取所有监控数据
public static Map<String, Object> getAllMonitorInfo() {
Map<String, Object> allInfo = new HashMap<>();
allInfo.put("timestamp", System.currentTimeMillis());
allInfo.put("memory", getMemoryInfo());
allInfo.put("thread", getThreadInfo());
allInfo.put("gc", getGCInfo());
allInfo.put("classLoading", getClassLoadingInfo());
allInfo.put("system", getSystemInfo());
allInfo.put("compilation", getCompilationInfo());
allInfo.put("runtime", getRuntimeInfo());
return allInfo;
}
// JVM运行时信息
public static Map<String, Object> getRuntimeInfo() {
Map<String, Object> runtimeInfo = new HashMap<>();
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
runtimeInfo.put("name", runtimeMXBean.getName());
runtimeInfo.put("vmName", runtimeMXBean.getVmName());
runtimeInfo.put("vmVersion", runtimeMXBean.getVmVersion());
runtimeInfo.put("vmVendor", runtimeMXBean.getVmVendor());
runtimeInfo.put("uptime", runtimeMXBean.getUptime());
runtimeInfo.put("startTime", runtimeMXBean.getStartTime());
// JVM参数
List<String> inputArguments = runtimeMXBean.getInputArguments();
runtimeInfo.put("jvmArguments", inputArguments);
// Classpath
runtimeInfo.put("classPath", runtimeMXBean.getClassPath());
// 系统属性
Map<String, String> systemProperties = runtimeMXBean.getSystemProperties();
runtimeInfo.put("systemProperties", systemProperties);
return runtimeInfo;
}
}
监控数据格式化输出
JVMInfoFormatter.java
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class JVMInfoFormatter {
private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 格式化字节大小为可读格式
public static String formatBytes(long bytes) {
if (bytes == 0) return "0 B";
final String[] units = {"B", "KB", "MB", "GB", "TB"};
int unitIndex = (int) (Math.log10(Math.abs(bytes)) / Math.log10(1024));
if (unitIndex >= units.length) {
unitIndex = units.length - 1;
}
double value = bytes / Math.pow(1024, unitIndex);
return String.format("%.2f %s", value, units[unitIndex]);
}
// 格式化内存信息
public static String formatMemoryInfo(Map<String, Object> memoryInfo) {
StringBuilder sb = new StringBuilder();
sb.append("========== 内存监控 ==========\n");
long heapMax = (Long) memoryInfo.get("heapMax");
long heapUsed = (Long) memoryInfo.get("heapUsed");
long heapCommitted = (Long) memoryInfo.get("heapCommitted");
sb.append("堆内存:");
sb.append("\n 最大: ").append(formatBytes(heapMax));
sb.append("\n 已用: ").append(formatBytes(heapUsed));
sb.append("\n 已分配: ").append(formatBytes(heapCommitted));
sb.append("\n 使用率: ").append(String.format("%.2f%%",
heapMax > 0 ? (double) heapUsed / heapMax * 100 : 0));
sb.append("\n\n非堆内存:");
sb.append("\n 已用: ").append(formatBytes((Long) memoryInfo.get("nonHeapUsed")));
sb.append("\n 已分配: ").append(formatBytes((Long) memoryInfo.get("nonHeapCommitted")));
// 内存池详情
@SuppressWarnings("unchecked")
List<Map<String, Object>> pools = (List<Map<String, Object>>) memoryInfo.get("memoryPools");
if (pools != null) {
sb.append("\n\n内存池详情:");
for (Map<String, Object> pool : pools) {
sb.append("\n ").append(pool.get("name"))
.append(" (").append(pool.get("type")).append("):");
MemoryUsage usage = (MemoryUsage) pool.get("usage");
if (usage != null) {
sb.append(" used=").append(formatBytes(usage.getUsed()))
.append(", max=").append(formatBytes(usage.getMax()))
.append(", committed=").append(formatBytes(usage.getCommitted()));
}
}
}
return sb.toString();
}
// 格式化线程信息
public static String formatThreadInfo(Map<String, Object> threadInfo) {
StringBuilder sb = new StringBuilder();
sb.append("\n========== 线程监控 ==========\n");
sb.append("当前线程数: ").append(threadInfo.get("threadCount"));
sb.append("\n峰值线程数: ").append(threadInfo.get("peakThreadCount"));
sb.append("\n守护线程数: ").append(threadInfo.get("daemonThreadCount"));
sb.append("\n总启动线程数: ").append(threadInfo.get("totalStartedThreadCount"));
sb.append("\n死锁线程数: ").append(threadInfo.get("deadlockedThreads"));
@SuppressWarnings("unchecked")
List<Map<String, Object>> threads = (List<Map<String, Object>>) threadInfo.get("threads");
if (threads != null) {
sb.append("\n\n线程状态统计:");
Map<String, Integer> stateCount = new HashMap<>();
for (Map<String, Object> thread : threads) {
String state = (String) thread.get("threadState");
stateCount.merge(state, 1, Integer::sum);
}
stateCount.forEach((state, count) ->
sb.append("\n ").append(state).append(": ").append(count));
}
return sb.toString();
}
// 格式化GC信息
public static String formatGCInfo(Map<String, Object> gcInfo) {
StringBuilder sb = new StringBuilder();
sb.append("\n========== GC监控 ==========\n");
sb.append("总GC次数: ").append(gcInfo.get("totalGcCount"));
sb.append("\n总GC时间: ").append(gcInfo.get("totalGcTime")).append(" ms");
@SuppressWarnings("unchecked")
List<Map<String, Object>> gcDetails = (List<Map<String, Object>>) gcInfo.get("gcDetails");
if (gcDetails != null) {
sb.append("\n\nGC详情:");
for (Map<String, Object> gc : gcDetails) {
sb.append("\n ").append(gc.get("name"))
.append(": 次数=").append(gc.get("collectionCount"))
.append(", 时间=").append(gc.get("collectionTime")).append("ms");
}
}
return sb.toString();
}
// 格式化系统信息
public static String formatSystemInfo(Map<String, Object> systemInfo) {
StringBuilder sb = new StringBuilder();
sb.append("\n========== 系统信息 ==========\n");
sb.append("操作系统: ").append(systemInfo.get("osName"))
.append(" ").append(systemInfo.get("osVersion"));
sb.append("\nCPU核心数: ").append(systemInfo.get("availableProcessors"));
sb.append("\n系统负载: ").append(systemInfo.get("systemLoadAverage"));
sb.append("\nCPU使用率: ").append(String.format("%.2f%%",
(Double) systemInfo.get("cpuUsage") * 100));
sb.append("\n进程CPU使用率: ").append(String.format("%.2f%%",
(Double) systemInfo.get("processCpuUsage") * 100));
sb.append("\n物理内存: 总=").append(formatBytes((Long) systemInfo.get("totalPhysicalMemory")))
.append(", 可用=").append(formatBytes((Long) systemInfo.get("freePhysicalMemory")));
return sb.toString();
}
// 格式化所有信息
public static String formatAllInfo(Map<String, Object> allInfo) {
StringBuilder sb = new StringBuilder();
long timestamp = (Long) allInfo.get("timestamp");
sb.append("===== JVM监控信息 ").append(SDF.format(new Date(timestamp))).append(" =====\n");
// 内存
@SuppressWarnings("unchecked")
Map<String, Object> memoryInfo = (Map<String, Object>) allInfo.get("memory");
sb.append(formatMemoryInfo(memoryInfo));
// 线程
@SuppressWarnings("unchecked")
Map<String, Object> threadInfo = (Map<String, Object>) allInfo.get("thread");
sb.append(formatThreadInfo(threadInfo));
// GC
@SuppressWarnings("unchecked")
Map<String, Object> gcInfo = (Map<String, Object>) allInfo.get("gc");
sb.append(formatGCInfo(gcInfo));
// 系统
@SuppressWarnings("unchecked")
Map<String, Object> systemInfo = (Map<String, Object>) allInfo.get("system");
sb.append(formatSystemInfo(systemInfo));
// 类加载
@SuppressWarnings("unchecked")
Map<String, Object> classInfo = (Map<String, Object>) allInfo.get("classLoading");
sb.append("\n========== 类加载监控 ==========\n");
sb.append("已加载类: ").append(classInfo.get("loadedClassCount"));
sb.append("\n总加载类: ").append(classInfo.get("totalLoadedClassCount"));
sb.append("\n卸载类数量: ").append(classInfo.get("unloadedClassCount"));
// JVM运行时
@SuppressWarnings("unchecked")
Map<String, Object> runtimeInfo = (Map<String, Object>) allInfo.get("runtime");
sb.append("\n========== JVM运行时 ==========\n");
sb.append("JVM名称: ").append(runtimeInfo.get("vmName"));
sb.append("\nJVM版本: ").append(runtimeInfo.get("vmVersion"));
sb.append("\n运行时间: ").append(formatUptime((Long) runtimeInfo.get("uptime")));
return sb.toString();
}
private static String formatUptime(long uptimeMillis) {
long days = uptimeMillis / (24 * 3600 * 1000);
long hours = (uptimeMillis % (24 * 3600 * 1000)) / (3600 * 1000);
long minutes = (uptimeMillis % (3600 * 1000)) / (60 * 1000);
long seconds = (uptimeMillis % (60 * 1000)) / 1000;
return String.format("%d天 %02d:%02d:%02d", days, hours, minutes, seconds);
}
}
监控服务类
MonitorService.java
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MonitorService implements AutoCloseable {
private final ScheduledExecutorService scheduler;
private final long intervalSeconds;
private PrintWriter logWriter;
private boolean logToFile;
public MonitorService(long intervalSeconds) {
this.intervalSeconds = intervalSeconds;
this.scheduler = Executors.newScheduledThreadPool(1);
}
public MonitorService(long intervalSeconds, String logFilePath) {
this(intervalSeconds);
this.logToFile = true;
try {
this.logWriter = new PrintWriter(new FileWriter(logFilePath, true), true);
} catch (IOException e) {
System.err.println("无法创建日志文件: " + e.getMessage());
this.logToFile = false;
}
}
public void start() {
System.out.println("JVM监控服务启动,每 " + intervalSeconds + " 秒采集一次");
scheduler.scheduleAtFixedRate(() -> {
try {
collectAndDisplay();
} catch (Exception e) {
System.err.println("监控采集失败: " + e.getMessage());
}
}, 0, intervalSeconds, TimeUnit.SECONDS);
}
private void collectAndDisplay() {
Map<String, Object> allInfo = JVMMonitor.getAllMonitorInfo();
String formattedInfo = JVMInfoFormatter.formatAllInfo(allInfo);
// 控制台输出
System.out.println(formattedInfo);
System.out.println("========================================");
// 文件输出
if (logToFile && logWriter != null) {
logWriter.println(formattedInfo);
logWriter.println("========================================");
}
}
@Override
public void close() {
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
}
if (logWriter != null) {
logWriter.close();
}
System.out.println("JVM监控服务已停止");
}
}
主程序入口
Main.java
import java.util.Map;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("=== JVM监控工具 ===");
System.out.println("1. 单次采集监控信息");
System.out.println("2. 定时监控(默认5秒间隔)");
System.out.println("3. 定时监控并保存日志");
System.out.print("请选择 (1/2/3): ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
// 单次采集
collectOnce();
break;
case 2:
System.out.print("请输入监控间隔(秒): ");
long interval = scanner.nextLong();
scanner.nextLine();
try (MonitorService service = new MonitorService(interval)) {
service.start();
System.out.println("按回车键停止监控...");
scanner.nextLine();
}
break;
case 3:
System.out.print("请输入监控间隔(秒): ");
interval = scanner.nextLong();
scanner.nextLine();
System.out.print("请输入日志文件路径(如: jvm_monitor.log): ");
String logPath = scanner.nextLine();
try (MonitorService service = new MonitorService(interval, logPath)) {
service.start();
System.out.println("按回车键停止监控...");
scanner.nextLine();
}
break;
default:
System.out.println("无效选择");
}
scanner.close();
}
private static void collectOnce() {
System.out.println("正在采集JVM监控信息...\n");
Map<String, Object> allInfo = JVMMonitor.getAllMonitorInfo();
String formattedInfo = JVMInfoFormatter.formatAllInfo(allInfo);
System.out.println(formattedInfo);
// 显示JVM参数
System.out.println("\n========== JVM启动参数 ==========");
@SuppressWarnings("unchecked")
Map<String, Object> runtimeInfo = (Map<String, Object>) allInfo.get("runtime");
@SuppressWarnings("unchecked")
java.util.List<String> jvmArgs = (java.util.List<String>) runtimeInfo.get("jvmArguments");
jvmArgs.forEach(arg -> System.out.println(" " + arg));
}
}
运行测试类
MonitorTest.java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class MonitorTest {
// 模拟内存使用
private static List<byte[]> memoryLeak = new ArrayList<>();
private static Random random = new Random();
// 模拟线程创建
private static List<Thread> threads = new ArrayList<>();
public static void main(String[] args) throws Exception {
System.out.println("启动JVM监控测试...");
// 显示初始监控信息
Map<String, Object> initialInfo = JVMMonitor.getAllMonitorInfo();
System.out.println(JVMInfoFormatter.formatAllInfo(initialInfo));
System.out.println("\n开始模拟负载...");
// 模拟内存分配
Thread memoryThread = new Thread(() -> {
try {
for (int i = 0; i < 100; i++) {
// 分配5MB内存
memoryLeak.add(new byte[5 * 1024 * 1024]);
System.out.println("分配内存: " + ((i + 1) * 5) + "MB");
Thread.sleep(500);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
memoryThread.start();
// 模拟线程创建
Thread threadThread = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
Thread t = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
t.start();
threads.add(t);
System.out.println("创建线程: " + t.getName());
Thread.sleep(300);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
threadThread.start();
// 运行10秒后显示监控信息
Thread.sleep(10000);
System.out.println("\n=== 运行10秒后的监控信息 ===");
Map<String, Object> afterInfo = JVMMonitor.getAllMonitorInfo();
System.out.println(JVMInfoFormatter.formatAllInfo(afterInfo));
// 清理
memoryLeak.clear();
for (Thread t : threads) {
t.interrupt();
}
// 触发GC
System.gc();
Thread.sleep(1000);
System.out.println("\n=== GC后的监控信息 ===");
Map<String, Object> gcAfterInfo = JVMMonitor.getAllMonitorInfo();
System.out.println(JVMInfoFormatter.formatAllInfo(gcAfterInfo));
System.out.println("\n测试完成");
}
}
运行说明
编译和运行:
# 编译 javac -d . *.java # 运行主程序 java Main # 运行测试程序 java MonitorTest # 使用JVM参数运行(推荐,便于观察) java -Xms256m -Xmx1024m -XX:+UseG1GC -XX:+PrintGCDetails Main
输出示例:
========== 内存监控 ==========
堆内存:
最大: 1.00 GB
已用: 256.00 MB
已分配: 512.00 MB
使用率: 25.00%
========== 线程监控 ==========
当前线程数: 5
峰值线程数: 12
守护线程数: 3
========== GC监控 ==========
总GC次数: 3
总GC时间: 150 ms
========== 系统信息 ==========
操作系统: Windows 10
CPU核心数: 8
CPU使用率: 15.00%
功能特点
- 全面监控:内存、线程、GC、类加载、系统、编译、运行时信息
- 实时采集:可配置采集频率
- 多种输出:控制台显示、文件日志
- 性能分析:支持死锁检测、内存池分析
- 易于扩展:模块化设计,方便添加新监控项
这个监控工具可以用于:
- JVM性能调优
- 内存泄漏排查
- 线程问题分析
- GC性能优化
- 生产环境监控
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播