文档章节

Classloader、NIO ByteBuffer.allocateDirect的回收 、一致性Hash

Yiwater
 Yiwater
发布于 2016/08/29 17:26
字数 1217
阅读 22
收藏 0

比较多的东西,写的比较杂乱,以后会写一些自己复习到的内容,或者新学习到的东西,尽量让自己写的东西有价值,对一天学习的内容有一个总结。

一、Classloader

1、过程

1)加载:查找并加载类的二进制数据。

将.class文件中的二进制数据读入到内存,将其放在运行时数据的方法区,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

非本地加载.class文件      urlclassloader

当加载完成之后,就进入连接阶段,连接阶段就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中

2)连接:
验证:确保被加载的类的正确性


准备:为类的静态变量分配内存,并初始化为默认值

当我的类中有静态变量时,eg:static int i = 6  ,会在这个阶段,为其分配内存4个字节,并初始化默认值0

解析:把类中的符号引用转换为直接引用。

在解析阶段,jvm会把类的二进制数据中的符号引用替换为直接引用
假设有个AAA类里面的aaa方法调用XXX类中bbb方法
public void aaa(){
    xxx.bbb(); //该调用在AAA的二进制中标示为符号引用
}
JVM将把这个符号引用替换为一个指针,指向XXX的bbb方法区的内存地址,该指针就是直接引用

3)初始化:为类的静态变量赋正确的初始值 int = 6

 

2、加载器

根类加载器Bootstrap native(c语言)实现

扩展类加载器Extension java实现

系统类加载器(也叫应用类加载器)System java实现

Bootstrap在整个程序开始启动的时候,会直接加载jdk下的lib文件下的类,Extension会加载jre下的lib下ext下的类,System会加载classpath下的类(包括在工程中lib下的第三方jar包,自己写的classloader),前面两个类加载器在启动的时候会将所有的类全部加载完毕,而后一个动态加载所需类,以下五种情况会加载类:

创建类实例     new Test()
访问类或接口静态变量以及赋值    int b=Test.a      Test.a=b
调用静态方法     Test.do()
反射调用  class.forname
初始化子类   class P   class T extend P       T.xxx
java虚拟机启动时标示为启动类的类    meta-inf

3、类的委托机制

 

二、NIO ByteBuffer.allocateDirect的回收

 ByteBuffer bd = ByteBuffer.allocateDirect(30);       
 ((DirectBuffer)bd).cleaner().clean();

ByteBuffer可以申请直接内存,但是很能做到主动回收,System.gc()只是向虚拟机通知该做一次fullgc,但是几时做,做没做不知道。((DirectBuffer)bd).cleaner().clean()可以做到回收,将你在堆外的对象进行一次强制类型转换,将其转化成一个堆内对象,”欺骗“虚拟机,这样就可以对堆外内存进行回收。

 

三、一致性Hash

这个就是一个小的demo,hashutil不是自己写的,整个demo用来表现一致性hash的一种思想

public class ConsistentHash {
    public static HashMap<Integer,String> hashMap = new HashMap();
    public static void dealNode(){
        HashUtil hash = new HashUtil();
        String realip1 = "172.16.204.112";
        String realip2 = "172.16.204.129";
        String realip3 = "172.16.204.104";
        int node1 = hash.Hash(realip1);
        int node2 = hash.Hash(realip2);
        int node3 = hash.Hash(realip3);
        hashMap.put(node1,realip1);
        hashMap.put(node2,realip2);
        hashMap.put(node3,realip3);
        putNode(node1,realip1);
        putNode(node1,realip2);
        putNode(node1,realip3);
        System.out.println("对真实节点ip处理完成......");
        System.out.println("开始布置虚拟节点......");
    }

    public static HashMap putNode(int node,String ip){
        for(int i = node;i<=65535;i=i+1000){
            hashMap.put(node,ip);
        }
        for(int i = node;i>=0;i=i-1000){
            hashMap.put(node,ip);
        }
        System.out.println("虚拟节点完成");
        return hashMap;
    }

    public static void virtualNode(){
        System.out.println("对到来的数据包进行分析......");
        String ip = "198.126.23.132";
        System.out.println("对数据来源IP进行Hash. . . . . .");
        HashUtil hashUtil = new HashUtil();
        int node = hashUtil.Hash(ip);
        while(hashMap.get(node)==null){
            node++;
        }
        System.out.println("将数据发送给真实ip"+ hashMap.get(node));
    }

    public static void main(String[] args) {
        dealNode();
        virtualNode();
    }
}
public class HashUtil {
    public static int Hash(String s) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                '0', '1', '2', '3', '4', '5' };
        try {
            byte[] btInput = s.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return Integer.parseInt(new String(str).substring(0, 8));
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
}

四、一些其他的内容

public class ObjectTest implements Serializable {
    public String name ="oooooooooo";
}
public class Test {
    public static void main(String[] args) {
        ObjectTest objectText = new ObjectTest();
        System.out.println(objectText.toString());
 }
}

当一个对象,没有序列化之前,在堆是一块一块的存放的(有点像hdfs存放文件)。序列化以后,在堆中划一块连续内存存放对象,当拿出来时也是一块的连续的内存。

© 著作权归作者所有

Yiwater
粉丝 1
博文 6
码字总数 3304
作品 0
天津
程序员
私信 提问
Java系列文章(全)

JVM JVM系列:类装载器的体系结构 JVM系列:Class文件检验器 JVM系列:安全管理器 JVM系列:策略文件 Java垃圾回收机制 深入剖析Classloader(一)--类的主动使用与被动使用 深入剖析Classloader(二...

www19
2017/07/04
0
0
JAVA堆外内存

JVM可以使用的内存分外2种:堆内存和堆外内存. 堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemoryError这个错误。 使用堆外内存,就是...

小叮当_加V
2016/11/04
41
0
Memcached(内存模型、内存回收机制)

memcached内存模型 基本概念page/slab/chunk Chunk属于slab,在一个slab里面有多个chunk Slab里面也有多个page。 1slab class(slab分类) = n slab 1page=1slab = n chunk(统一长度) page ...

这很耳东先生
2018/11/30
0
0
2019年阿里Java面试必问:JVM与性能优化+Redis+设计模式+分布式

前言 一年之计在于春 金三银四已经要到来,2019的新的开始,作为一个开发人员,你是否面上了自己理想的公司,薪资达到心中理想的高度? 面试:如果不准备充分的面试,完全是浪费时间,更是对...

java知识分子
02/18
0
0
java之HeapByteBuffer&DirectByteBuffer以及回收DirectByte

byte buffer一般在网络交互过程中java使用得比较多,尤其是以NIO的框架中; 看名字就知道是以字节码作为缓冲的,先buffer一段,然后flush到终端。 而本文要说的一个重点就是HeapByteBuffer与...

梁杰_Jack
2015/03/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Feign Retryer的默认重试策略测试

1、Feign配置 @Configurationpublic class FeignConfig { @Value("${coupon_service.url:http://localhost:8081}") private String couponServiceUrl; @Bean publ......

moon888
32分钟前
1
0
关于不同域名下的session共享问题

如果登录,首页,分类,列表,产品都在不同的二级域名下,主域名不变,一定要保证里面的版本问题,不能为了更新而更新,这样哪个下面的session都访问不了。

dragon_tech
34分钟前
2
0
iOS 中文拼音互转(好东西记录一下)

PinYin4Objc

_____1____
42分钟前
1
0
fabric private data实战

Hyperledger Fabric private data是1.2版本引入的新特性,fabric private data是利用旁支数据库(SideDB)来保存若干个通道成员之间的私有数据,从而在通道之上又提供了一层更灵活的数据保护...

汇智网教程
42分钟前
1
0
es之聚合查询汇总

记录一下最近用到的es聚合查询,感觉常见的应该多遇上了,下午抽空更新

我真是小菜鸡
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部