1. 程式人生 > >java-JVM

java-JVM

ima 需要 服務 rtu 命令行 適配器 perm 指定 map

JVM
----------
    java virtual machine.
    java runtime data area .

    1.method area
        方法區
        共享

    2.java stack
        棧區,
        線程
        非共享
        壓入stack frame(method frame)

    3.native method stack
        本地方法棧
        非共享

    4.heap
        堆
        共享
        a)堆內內存
            
1)old 2)young 2.1)eden 2.2)survivor 2.2.1)from(s1) 2.2.2)to(s2) 內存碎片整理. b)非堆內存 Metaspace code cache compressed class space c)離堆內存 OS
- JVM [調參] -Xss -Xms -Xmx -Xmn //年輕代 -XX:NewSize -XX:MaxNewSize // -XX:NewRatio -XX:SurvivorRatio //eden區是單個幸存區的倍數 -XX:MetaspaceSize //元空間 -XX:MaxMetaspaceSize // -XX:PermSize
-XX:MaxPermSize 5.program counter register 程序計數器 非共享 [GC] 垃圾回收,盡量回收。 沒有任何一個指針能夠直接或間接到達對象。 //顯式回收 bytes = null ; System.gc() [工具軟件] jvisualvm -> visual gc jconsole -> jmap -> 命令行 jmap -heap xxx Class.forName("加載類") ; ClassLoader ---------------- 類加載主要工作是類路徑映射和文件定位。 com.it18zhang.java.io.MyInpuStream -> com/it18zhang/java/io/MyInpuStream.class ClassLoader 類使用委托模型來搜索類和資源。 每個 ClassLoader 實例都有一個相關的父類加載器。需要查找類或資源時,ClassLoader 實例會在試圖 親自查找類或資源之前,將搜索類或資源的任務委托給其父類加載器。 虛擬機的內置類加載器(稱為 "bootstrap class loader")本身沒有父類加載器, 但是可以將它用作 ClassLoader 實例的父類加載器。 //類初始化過程 靜態代碼塊在類加載期間調用,只調用一次。 Class.forName(...,false, ) @Test public void test1() throws Exception { System.out.println("hello world"); ClassLoader loader = ClassLoader.getSystemClassLoader() ; Class clazz = Class.forName("com.it18zhang.domain.Person",false,loader); System.out.println("hello world"); System.out.println("hello world"); System.out.println("hello world"); System.out.println("hello world"); Person p = null ; System.out.println(); Class clz = Person.class ; System.out.println(); p = new Person(); System.out.println(); System.out.println(); System.out.println(); } 自定義類加載器 ----------------- package com.it18zhang.classloader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; /** * 在定義類加載器 */ public class MyClassLoader extends ClassLoader { protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] data = loadClassBytes(name) ; return defineClass(data,0,data.length) ; } /** * 加載類的字節碼文件 */ private byte[] loadClassByrtes(String name){ try{ File file = new File("d:/java" , name + ".class") ; FileInputStream fis = new FileInputStream(file) ; ByteArrayOutputStream baos = new ByteArrayOutputStream() ; int len = 0 ; byte[] buf = new byte[1024] ; while((len = fis.read(buf)) != -1){ baos.write(buf , 0 ,len); } fis.close(); baos.close(); return baos.toByteArray() ; } catch (Exception e){ e.printStackTrace(); } return null ; } } /** * 自定義類加載器 */ @Test public void test3() throws Exception { MyClassLoader loader = new MyClassLoader() ; Class clazz = loader.loadClass("HelloWorld") ; Object obj = clazz.newInstance(); Method m = clazz.getDeclaredMethod("sayHello") ; m.invoke(obj) ; System.out.println("over"); } NIO -------------- new io, 新型IO. jdk1.4 tcp //transfer control protocal udp //用戶數據報協議 ServerSocket //服務器套接字 Socket //套接字 分線程 : 同步的,阻塞的。 ss.accept() socket.read() ; OutputStream // InputStream // 非阻塞 , netty [術語] 1.Buffer, 緩沖區 capacity : 容量,長度 limit : 限制,能夠使用的元素個數。 position :位置,指針的索引位置。 mark :記號 reset , 0 <= mark <= position <= limit <= capacity 1.flip() 拍板。 2.Channel 打開的連接,連接到實體(硬件,File,Socket) package com.it18zhang.java.test; import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; /** * */ public class TestNIO { @Test public void test1() throws Exception { for(int i = 1024 ; i <= 1024 * 1024 * 2; i = i * 2){ copyFile("d:/Koala.gif" , "e:/1.gif", i) ; } } /** * 拷貝文件,指定不同緩沖區大小 */ public static void copyFile(String srcFile ,String destFile , int bufSize) throws Exception { File targFile = new File(destFile) ; if(targFile.exists()){ targFile.delete() ; } // FileInputStream fis = new FileInputStream(srcFile) ; //得到源文件通道 FileChannel srcFC = fis.getChannel(); // FileOutputStream fos = new FileOutputStream(destFile) ; FileChannel outFC = fos.getChannel() ; //緩沖區 long start = System.nanoTime() ; ByteBuffer buf = ByteBuffer.allocateDirect(bufSize) ; while(srcFC.read(buf) != -1){ buf.flip() ; outFC.write(buf) ; buf.clear(); } System.out.println(bufSize + "\t : " + (System.nanoTime() - start)); srcFC.close(); fis.close(); outFC.close(); fos.close(); } /** * 分配內存 */ @Test public void test2(){ int len = 1024 * 1024 * 500 ; //堆內內存 ByteBuffer.allocate(len) ; //離堆內存 ByteBuffer.allocateDirect(len) ; System.out.println(); } } // ByteBuffer.allocate() ==> HeapByteBuffer //離堆 ByteBuffer.allocateDirect() ==> DirectByteBuffer System.gc() ; NIO操縱離堆內存,手動回收離隊內存,使用反射手段。 ----------------------------------------------- @Test public void test2() throws Exception { int len = 1024 * 1024 * 500 ; // //堆內內存 // ByteBuffer buf = ByteBuffer.allocate(len) ; // System.gc(); // buf = null ; // System.gc(); // buf.clear() ; // System.gc(); //離堆內存 ByteBuffer buf = ByteBuffer.allocateDirect(len) ; Method m = buf.getClass().getDeclaredMethod("cleaner") ; m.setAccessible(true); Cleaner cleaner = (Cleaner) m.invoke(buf); cleaner.clean(); buf.put((byte)100) ; buf.get(); System.gc(); System.out.println(); System.out.println(); System.out.println(); } @Test public void test3() throws Exception { RandomAccessFile raf = new RandomAccessFile("d:/java/1.txt" ,"rw") ; FileChannel fc = raf.getChannel(); MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_WRITE , 2,5) ; buf.put((byte)97) ; buf.put((byte)98) ; buf.put((byte)99) ; buf.flip(); buf.put((byte) 100) ; buf.put((byte) 100) ; buf.put((byte) 100) ; fc.close(); } 機械硬盤 ------------------ 100m/s. 零拷貝 ------------------ 常規 64k 600m 475,276,088 零拷貝 64k 600m 349,630,104 /** * 測試正常拷貝 */ @Test public void testNormalCopy() throws Exception { FileInputStream fis = new FileInputStream("D:\\downloads\\iso\\CentOS-7-x86_64-Minimal-1511.iso") ; long start = System.nanoTime() ; FileOutputStream fos = new FileOutputStream("e:/1.iso") ; byte[] bytes = new byte[64 * 1024] ; int len = -1 ; while((len = fis.read(bytes)) != -1){ fos.write(bytes,0,len); } fos.close(); fis.close(); System.out.println(System.nanoTime() - start); } /** * * @throws Exception */ @Test public void testZeroCopy() throws Exception { long start = System.nanoTime() ; File f = new File("D:\\downloads\\iso\\CentOS-7-x86_64-Minimal-1511.iso") ; FileInputStream fis = new FileInputStream(f) ; FileOutputStream fos = new FileOutputStream("f:/1.iso") ; fis.getChannel().transferTo(0, f.length(), fos.getChannel()) ; fos.close(); fis.close(); System.out.println(System.nanoTime() - start); } 網絡適配器工作模式 -------------------- 單工 //只能向一個方向傳輸數據。 雙工 //可以雙向傳輸數據 半雙工 //同一時刻只能向一方傳輸。 全雙工 //同一時刻只能向一方傳輸。 NIO Socket -------------- 1.ServerSocketChannel 服務器通道, ServerSocket 配置阻塞模式. ServerSocketChannel.open() 2.SockdetChannel connect(); 3.Selector 挑選器, 通道需要在該組件中註冊,註冊後會產生key(SelectionKey),該key關聯到channel 註冊生成的key存放在keys集合中。 內部維護三個集和 1.keys 存放所有註冊的key 2.selectedkeys 存放挑選出來的key,通道上發生了自己感興趣的事件。 處理完該集合後,需要對該集合進行清空處理。 3.cancelledkeys 存放即將被撤銷的通道的key。 4.SelectionKey 註冊產生的key對象,內部封裝channel引用,該興趣的事件。 5.channel同buffer協同 channel.read()|write() 6.NIO核心是非阻塞 不需要創建大量線程,避免cpu在大量線程上下文之間進行切換,cpu運行效率很高。

java-JVM