JVM自己提供了一組管理的API,經過該API,咱們能夠獲取獲得JVM內部主要運行信息,包括內存各代的數據、JVM當前全部線程及其棧相關信 息等等。各類JDK自帶的剖析工具,包括jps、jstack、jinfo、jstat、jmap、jconsole等,都是基於此API開發的。本篇對 這部份內容進行一個詳細的說明。html
參考:http://java.sun.com/javase/6/docs/api/java/lang/management/package-summary.html
1、Management API
咱們先看一下從Sun JVM咱們能夠獲取到哪些信息,以下圖(來自於JConsole的MBean部分的截圖):
1.HotSpotDiagnostic:非標準的監控JMX,這塊是Sun JVM自帶的,主要提供了兩個功能java
- 修改JVM的啓動參數(譬如在不須要重啓的狀況下設置-XX:+HeapDumpOnOutOfMemoryError參數使得JVM內存不足的時候自動dump出堆空間到文件提供後續分析)
- Dump堆信息到文件,能夠猜想jmap工具是基於此功能來完成的
咱們經過com.sun.management.HotSpotDiagnosticMXBean定義瞭解其主要功能
編程
- public interface HotSpotDiagnosticMXBean
- {
- void dumpHeap(String s, boolean flag) throws IOException;
- List getDiagnosticOptions();
- VMOption getVMOption(String s);
- void setVMOption(String s, String s1);
- }
- public interface HotSpotDiagnosticMXBean
- {
- void dumpHeap(String s, boolean flag) throws IOException;
- List getDiagnosticOptions();
- VMOption getVMOption(String s);
- void setVMOption(String s, String s1);
- }
2.ClassLoading:加載的類的整體信息,咱們能夠經過此MBean獲取到JVM加載的類定義的整體信息,能夠猜想JConsole的類功能就 是經過此MBean來提供的。咱們能夠經過java.lang.management.ClassLoadingMXBean定義瞭解其提供的主要功能api
- public interface ClassLoadingMXBean {
- public long getTotalLoadedClassCount();
- public int getLoadedClassCount();
- public long getUnloadedClassCount();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- }
- public interface ClassLoadingMXBean {
- public long getTotalLoadedClassCount();
- public int getLoadedClassCount();
- public long getUnloadedClassCount();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- }
3.Compilation:提供JVM的JIT(Just In Time)編譯器(將bytecode編譯成native code)的信息,咱們能夠經過java.lang.management.CompilationMXBean定義瞭解其提供的主要功能架構
- public interface CompilationMXBean {
- public java.lang.String getName();
- public boolean isCompilationTimeMonitoringSupported();
- public long getTotalCompilationTime();
- }
- public interface CompilationMXBean {
- public java.lang.String getName();
- public boolean isCompilationTimeMonitoringSupported();
- public long getTotalCompilationTime();
- }
4.GarbageCollector:垃圾回收器信息,譬如在如上圖中,咱們啓動的JVM會包含一個Copy垃圾回收器(用於Young Gen垃圾回收)和一個MarkAndSweep垃圾回收器(用於Tenured Gen垃圾回收)。咱們能夠經過java.lang.management.GarbageCollectorMXBean定義瞭解其提供的主要功能工具
- public interface GarbageCollectorMXBean extends MemoryManagerMXBean {
- public long getCollectionCount();
- public long getCollectionTime();
- }
- public interface GarbageCollectorMXBean extends MemoryManagerMXBean {
- public long getCollectionCount();
- public long getCollectionTime();
- }
java.lang.management.MemoryManagerMXBean定義是性能
- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
除了如上信息,Sun JVM在實現上還提供了一個額外的信息LastGCInfo,見com.sun.management.GarbageCollectorMXBean定義fetch
- public interface GarbageCollectorMXBean
- extends java.lang.management.GarbageCollectorMXBean
- {
- GcInfo getLastGcInfo();
- }
- public interface GarbageCollectorMXBean
- extends java.lang.management.GarbageCollectorMXBean
- {
- GcInfo getLastGcInfo();
- }
咱們能夠經過下面的截圖瞭解GcInfo包含的主要信息
其中java.lang.management.MemoryUsage後續能夠看說明
5.內存相關
能夠猜想,JConsole的內存部分的功能都是經過此部分的相關Bean來完成的。
1)Memory/MemoryManager:內存塊相關信息,經過這MBean咱們能夠獲取到內存的整體信息,並能夠經過提供的gc操做進行強制gc 的功能(System.gc())。咱們能夠經過java.lang.management.MemoryMXBean和 java.lang.management.MemoryManagerMXBean瞭解其主要提供的功能url
- public interface MemoryMXBean {
- public int getObjectPendingFinalizationCount();
- public MemoryUsage getHeapMemoryUsage();
- public MemoryUsage getNonHeapMemoryUsage();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- public void gc();
- }
- public interface MemoryMXBean {
- public int getObjectPendingFinalizationCount();
- public MemoryUsage getHeapMemoryUsage();
- public MemoryUsage getNonHeapMemoryUsage();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- public void gc();
- }
其中java.lang.management.MemoryUsage咱們能夠經過下圖來了解其提供的主要信息spa
- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
- public interface MemoryManagerMXBean {
- public String getName();
- public boolean isValid();
- public String[] getMemoryPoolNames();
- }
2)MemoryPool:經過該MBean能夠了解JVM各內存塊的信息,譬如對於Sun JVM,目前包括Eden Space、Suvivor Space、Tenured Gen、CodeCache、Perm Gen,能夠猜想JConsole的內存監控功能就是經過此MBean來作到的。咱們能夠經過 java.lang.management.MemoryPoolMXBean瞭解其主要提供的功能
- public interface MemoryPoolMXBean {
- public String getName();
- public MemoryType getType();
- public MemoryUsage getUsage();
- public MemoryUsage getPeakUsage();
- public void resetPeakUsage();
- public boolean isValid();
- public String[] getMemoryManagerNames();
- public long getUsageThreshold();
- public void setUsageThreshold(long threshold);
- public boolean isUsageThresholdExceeded();
- public long getUsageThresholdCount();
- public boolean isUsageThresholdSupported();
- public long getCollectionUsageThreshold();
- public void setCollectionUsageThreshold(long threhsold);
- public boolean isCollectionUsageThresholdExceeded();
- public long getCollectionUsageThresholdCount();
- public MemoryUsage getCollectionUsage();
- public boolean isCollectionUsageThresholdSupported();
- }
- public interface MemoryPoolMXBean {
- public String getName();
- public MemoryType getType();
- public MemoryUsage getUsage();
- public MemoryUsage getPeakUsage();
- public void resetPeakUsage();
- public boolean isValid();
- public String[] getMemoryManagerNames();
- public long getUsageThreshold();
- public void setUsageThreshold(long threshold);
- public boolean isUsageThresholdExceeded();
- public long getUsageThresholdCount();
- public boolean isUsageThresholdSupported();
- public long getCollectionUsageThreshold();
- public void setCollectionUsageThreshold(long threhsold);
- public boolean isCollectionUsageThresholdExceeded();
- public long getCollectionUsageThresholdCount();
- public MemoryUsage getCollectionUsage();
- public boolean isCollectionUsageThresholdSupported();
- }
6.系統運行信息
1)OperatingSystem:經過該MBean咱們能夠了解到JVM所運行在的操做系統上的一些相關信息,經過java.lang.management.OperatingSystemMXBean定義咱們能夠了解到其主要提供的功能
- public interface OperatingSystemMXBean {
- public String getName();
- public String getArch();
- public String getVersion();
- public int getAvailableProcessors();
- public double getSystemLoadAverage();
- }
- public interface OperatingSystemMXBean {
- public String getName();
- public String getArch();
- public String getVersion();
- public int getAvailableProcessors();
- public double getSystemLoadAverage();
- }
SunJVM在此基礎上提供更多的一些信息,能夠經過com.sun.management.OperatingSystemMXBean瞭解一些額外能夠獲取到的信息
- public interface OperatingSystemMXBean
- extends java.lang.management.OperatingSystemMXBean
- {
- long getCommittedVirtualMemorySize();
- long getTotalSwapSpaceSize();
- long getFreeSwapSpaceSize();
- long getProcessCpuTime();
- long getFreePhysicalMemorySize();
- long getTotalPhysicalMemorySize();
- }
- public interface OperatingSystemMXBean
- extends java.lang.management.OperatingSystemMXBean
- {
- long getCommittedVirtualMemorySize();
- long getTotalSwapSpaceSize();
- long getFreeSwapSpaceSize();
- long getProcessCpuTime();
- long getFreePhysicalMemorySize();
- long getTotalPhysicalMemorySize();
- }
2)Runtime:經過該MBean獲取獲取到JVM一些相關的信息,經過java.lang.management.RuntimeMXBean能夠了解其主要提供的功能
- public interface RuntimeMXBean {
- public String getName();
- public String getVmName();
- public String getVmVendor();
- public String getVmVersion();
- public String getSpecName();
- public String getSpecVendor();
- public String getSpecVersion();
- public String getManagementSpecVersion();
- public String getClassPath();
- public String getLibraryPath();
- public boolean isBootClassPathSupported();
- public String getBootClassPath();
- public java.util.List<String> getInputArguments();
- public long getUptime();
- public long getStartTime();
- public java.util.Map<String, String> getSystemProperties();
- }
- public interface RuntimeMXBean {
- public String getName();
- public String getVmName();
- public String getVmVendor();
- public String getVmVersion();
- public String getSpecName();
- public String getSpecVendor();
- public String getSpecVersion();
- public String getManagementSpecVersion();
- public String getClassPath();
- public String getLibraryPath();
- public boolean isBootClassPathSupported();
- public String getBootClassPath();
- public java.util.List<String> getInputArguments();
- public long getUptime();
- public long getStartTime();
- public java.util.Map<String, String> getSystemProperties();
- }
能夠經過RuntimeMXBean.getUptime()和OperatingSystemMXBean. getProcessCpuTime()來計算JVM佔用的系統CPU比例的狀況,JConsole的CPU視圖就是經過這種方式計算的。
7.Threading:能夠經過該MBean獲取線程信息,包括線程狀態、執行棧等。能夠經過java.lang.management.ThreadMXBean瞭解其提供的主要功能
- public interface ThreadMXBean {
- public int getThreadCount();
- public int getPeakThreadCount();
- public long getTotalStartedThreadCount();
- public int getDaemonThreadCount();
- public long[] getAllThreadIds();
- public ThreadInfo getThreadInfo(long id);
- public ThreadInfo[] getThreadInfo(long[] ids);
- public ThreadInfo getThreadInfo(long id, int maxDepth);
- public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);
- public boolean isThreadContentionMonitoringSupported();
- public boolean isThreadContentionMonitoringEnabled();
- public void setThreadContentionMonitoringEnabled(boolean enable);
- public long getCurrentThreadCpuTime();
- public long getCurrentThreadUserTime();
- public long getThreadCpuTime(long id);
- public long getThreadUserTime(long id);
- public boolean isThreadCpuTimeSupported();
- public boolean isCurrentThreadCpuTimeSupported();
- public boolean isThreadCpuTimeEnabled();
- public void setThreadCpuTimeEnabled(boolean enable);
- public long[] findMonitorDeadlockedThreads();
- public void resetPeakThreadCount();
- public long[] findDeadlockedThreads();
- public boolean isObjectMonitorUsageSupported();
- public boolean isSynchronizerUsageSupported();
- public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers);
- public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers);
- }
- public interface ThreadMXBean {
- public int getThreadCount();
- public int getPeakThreadCount();
- public long getTotalStartedThreadCount();
- public int getDaemonThreadCount();
- public long[] getAllThreadIds();
- public ThreadInfo getThreadInfo(long id);
- public ThreadInfo[] getThreadInfo(long[] ids);
- public ThreadInfo getThreadInfo(long id, int maxDepth);
- public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);
- public boolean isThreadContentionMonitoringSupported();
- public boolean isThreadContentionMonitoringEnabled();
- public void setThreadContentionMonitoringEnabled(boolean enable);
- public long getCurrentThreadCpuTime();
- public long getCurrentThreadUserTime();
- public long getThreadCpuTime(long id);
- public long getThreadUserTime(long id);
- public boolean isThreadCpuTimeSupported();
- public boolean isCurrentThreadCpuTimeSupported();
- public boolean isThreadCpuTimeEnabled();
- public void setThreadCpuTimeEnabled(boolean enable);
- public long[] findMonitorDeadlockedThreads();
- public void resetPeakThreadCount();
- public long[] findDeadlockedThreads();
- public boolean isObjectMonitorUsageSupported();
- public boolean isSynchronizerUsageSupported();
- public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers);
- public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers);
- }
2、編程獲取到JVM Manage信息
咱們能夠經過JMX的方式讀取到JVM Manage定義的MBean,以下是3種獲取方法
1.監控應用與被監控應用位於同一JVM
- MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(server,
- "java.lang:type=Runtime", RuntimeMXBean.class);
- MBeanServer server = <span style="BACKGROUND-COLOR: #00ff40; COLOR: black; " id="casearchresult"><strong>ManagementFactory</strong></span>.getPlatformMBeanServer();
- RuntimeMXBean rmxb = <span style="BACKGROUND-COLOR: #00ff40; COLOR: black; " id="casearchresult"><strong>ManagementFactory</strong></span>.newPlatformMXBeanProxy(server,
- "java.lang:type=Runtime", RuntimeMXBean.class);
2.監控應用與被監控應用不位於同一JVM
1)首先在被監控的JVM的啓動參數中加入以下的啓動參數以啓JVM代理
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=127.0.0.1:8000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false
2)鏈接到代理上
- JMXServiceURL url = new JMXServiceURL(
- "service:jmx:rmi:///jndi/rmi://127.0.0.1:8000/jmxrmi");
- JMXConnector connector = JMXConnectorFactory.connect(url);
- RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector
- .getMBeanServerConnection(),"java.lang:type=Runtime",
- RuntimeMXBean.class);
- JMXServiceURL url = new JMXServiceURL(
- "service:jmx:rmi:///jndi/rmi://127.0.0.1:8000/jmxrmi");
- JMXConnector connector = JMXConnectorFactory.connect(url);
- RuntimeMXBean rmxb = <span style="BACKGROUND-COLOR: #00ff40; COLOR: black; " id="casearchresult"><strong>ManagementFactory</strong></span>.newPlatformMXBeanProxy(connector
- .getMBeanServerConnection(),"java.lang:type=Runtime",
- RuntimeMXBean.class);
3.監控應用與被監控應用不位於同一JVM但在同一物理主機上(2的特化狀況,經過進程Attach)
咱們使用JDK工具,如jmap、jstack等的時候,工具所在的JVM固然與被監控的JVM不是同一個,因此不能使用方式1,被監控的JVM通常也不 會在啓動參數中增長JMX的支持,因此方式2也沒有辦法。還好Sun JVM給咱們提供了第3種非標準的方式,就是經過Attach到被監控的JVM進程,並在被監控的JVM中啓動一個JMX代理,而後使用該代理經過2的方 式鏈接到被監控的JVM的JMX上。下面是一個使用範例,因爲裏面使用到的知識涉及到Java Instrutment(JVMTI的一個技術的Java實現)和Attach API,所以此處不作詳細解析,在後續看完Java Instrutment和Attach API天然就會明白。(注意,僅在JDK6+中支持,另外,運行須要jdk的tools.jar包)
- VirtualMachine virtualmachine = VirtualMachine.attach("5656");
-
- String javaHome = virtualmachine.getSystemProperties().getProperty("java.home");
- String jmxAgent = javaHome + File.separator + "lib" + File.separator + "management-agent.jar";
- virtualmachine.loadAgent(jmxAgent, "com.sun.management.jmxremote");
-
- Properties properties = virtualmachine.getAgentProperties();
- String address = (String)properties.get("com.sun.management.jmxremote.localConnectorAddress");
-
- virtualmachine.detach();
-
- JMXServiceURL url = new JMXServiceURL(address);
- JMXConnector connector = JMXConnectorFactory.connect(url);
- RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector
- .getMBeanServerConnection(), "java.lang:type=Runtime",RuntimeMXBean.class);
- VirtualMachine virtualmachine = VirtualMachine.attach("5656");
-
- String javaHome = virtualmachine.getSystemProperties().getProperty("java.home");
- String jmxAgent = javaHome + File.separator + "lib" + File.separator + "management-agent.jar";
- virtualmachine.loadAgent(jmxAgent, "com.sun.management.jmxremote");
-
- Properties properties = virtualmachine.getAgentProperties();
- String address = (String)properties.get("com.sun.management.jmxremote.localConnectorAddress");
-
- virtualmachine.detach();
-
- JMXServiceURL url = new JMXServiceURL(address);
- JMXConnector connector = JMXConnectorFactory.connect(url);
- RuntimeMXBean rmxb = <span style="BACKGROUND-COLOR: #00ff40; COLOR: black; " id="casearchresult"><strong>ManagementFactory</strong></span>.newPlatformMXBeanProxy(connector
- .getMBeanServerConnection(), "java.lang:type=Runtime",RuntimeMXBean.class);
3、結束語
能夠看到,經過標準的接口,咱們已經能夠得到運行的JVM很詳細的信息,從運行JVM、操做系統,到內存、GC和線程,經過這些標準的接口咱們已經能夠對 JVM進行功能完善的監控。可是僅此是不夠的,這部分接口描述的主要是JVM的整體性的信息,而沒法提供更多的細節。在下一部分,咱們將使用JPDA來更 深刻地瞭解JVM內部信息更細節的信息,並瞭解咱們如何經過JVM TI實現自動的性能監控
軟件包 java.lang.management 提供管理接口,用於監視和管理 Java 虛擬機以及 Java 虛擬機在其上運行的操做系統。
它同時容許從本地和遠程對正在運行的 Java 虛擬機進行監視和管理。
管理接口
ClassLoadingMXBean Java 虛擬機的類加載系統。
CompilationMXBean Java 虛擬機的編譯系統。
MemoryMXBean Java 虛擬機的內存系統。
ThreadMXBean Java 虛擬機的線程系統。
RuntimeMXBean Java 虛擬機的運行時系統。
OperatingSystemMXBean Java 虛擬機在其上運行的操做系統。
GarbageCollectorMXBean Java 虛擬機中的垃圾回收器。
MemoryManagerMXBean Java 虛擬機中的內存管理器。
MemoryPoolMXBean Java 虛擬機中的內存池。
示例以下:
import java.lang.management.ClassLoadingMXBean;
import java.lang.management.CompilationMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.ThreadMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.MemoryPoolMXBean;
import java.util.List;
public class JVM {
public static void main(String[] args) {
//Java 虛擬機線程系統的管理接口 ThreadMXBean
ThreadMXBean th=(ThreadMXBean)ManagementFactory.getThreadMXBean() ;
System.out.println("活動線程的當前數目"+th.getThreadCount());
System.out.println("返回活動守護線程的當前數目"+th.getDaemonThreadCount());
System.out.println("Java 虛擬機啓動或峯值重置以來峯值活動線程計數"+th.getPeakThreadCount());
System.out.println("返回當前線程的總 CPU 時間"+th.getCurrentThreadUserTime());
System.out.println("當前線程在用戶模式中執行的 CPU 時間"+th.getCurrentThreadUserTime());
//Java 虛擬機的運行時系統的管理接口。 RuntimeMXBean
RuntimeMXBean run=(RuntimeMXBean)ManagementFactory.getRuntimeMXBean();
System.out.println("正在運行的 Java 虛擬機的名稱"+run.getName());
System.out.println("Java 虛擬機規範名稱"+run.getSpecName());
System.out.println("返回 Java 庫路徑"+run.getLibraryPath());
System.out.println("系統類加載器用於搜索類文件的 Java 類路徑"+run.getClassPath());
//用於操做系統的管理接口,Java 虛擬機在此操做系統上運行 OperatingSystemMXBean
OperatingSystemMXBean op=(OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
System.out.println("返回操做系統的架構"+op.getArch());
System.out.println("返回操做系統名稱"+op.getName());
System.out.println("返回操做系統的版本"+op.getVersion());
System.out.println("Java 虛擬機可使用的處理器數目"+op.getAvailableProcessors());
//內存池的管理接口。內存池表示由 Java 虛擬機管理的內存資源,
//由一個或多個內存管理器對內存池進行管理 MemoryPoolMXBean
List<MemoryPoolMXBean> list=ManagementFactory.getMemoryPoolMXBeans();
for(MemoryPoolMXBean mem:list){
System.out.println("Java 虛擬機啓動以來或自峯值重置以來此內存池的峯值內存使用量"+mem.getPeakUsage());
System.out.println("返回此內存池的類型"+mem.getType());
System.out.println("內存使用量超過其閾值的次數"+ mem.getUsage());
}
//Java 虛擬機內存系統的管理接口。 MemoryMXBean
MemoryMXBean mem=(MemoryMXBean)ManagementFactory.getMemoryMXBean();
System.out.println(" 返回用於對象分配的堆的當前內存使用量"+mem.getHeapMemoryUsage());
System.out.println("Java 虛擬機使用的非堆內存的當前內存使用量"+mem.getNonHeapMemoryUsage());
// Java 虛擬機的編譯系統的管理接口 CompilationMXBean
CompilationMXBean com=(CompilationMXBean)ManagementFactory.getCompilationMXBean();
System.out.println("即時 (JIT) 編譯器的名稱"+com.getName());
System.out.println("在編譯上花費的累積耗費時間的近似值(毫秒)"+com.getTotalCompilationTime());
//Java 虛擬機的類加載系統的管理接口 ClassLoadingMXBean
ClassLoadingMXBean cl=(ClassLoadingMXBean)ManagementFactory.getClassLoadingMXBean();
System.out.println("當前加載到 Java 虛擬機中的類的數量"+cl.getLoadedClassCount());
System.out.println("Java 虛擬機開始執行到目前已經加載的類的總數"+cl.getTotalLoadedClassCount());
System.out.println("Java 虛擬機開始執行到目前已經卸載的類的總數"+cl.getUnloadedClassCount());
}
}
- public class TestExcho {
- public static void main(String[] args) throws Exception{
- MBeanServer server = ManagementFactory.getPlatformMBeanServer();
- ObjectName name = new ObjectName("com.demo.mbean:type=Excho");
- Echo ei =new Echo();
- server.registerMBean(ei,name);
- server.invoke(name, "setName", new Object[] { "jack"}, new String[] {"java.lang.String"});
- server.invoke(name, "showName", null, null);
- String yourName = (String)server.invoke(name, "fetchName", new Object[] { "mimi",10}, new String[] {"java.lang.String","int"});
- System.out.println("~~~"+yourName);
- CompositeData d = (CompositeData) server.invoke(name, "fetchConfig", null, null);
- String fn = (String)d.get("firstName");
- String ln = (String)d.get("lastName");
- System.out.println("~@@@~~"+fn+"@@"+ln);
- int num = (Integer)server.getAttribute(name, "Num");
- System.out.println("~OOOOO~~"+num);
- Thread.currentThread().sleep(Integer.MAX_VALUE);
- }
- }