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运行效率很高。