java-JVM-1

回顾
--------------
    1、并发库下的重入锁
        相较于synchronized来讲,cpu资源消耗少。粒度更细,可以控制到共享读锁和
        独占写锁,底层实现Unsafe对数字的控制实现,这些数字控制都是原子量实现。
        原子量底层控制实现原理是CAS(CompareAndSwap,比较并交换,反复尝试的过程,
        而不是将cpu阻塞)。tryLock()尝试上锁,如果得不到,即刻返回。
        java.util.concurrent.ReentrantLock            //可重入锁
        java.util.concurrent.ReentrantReadWriteLock    //可重入读写锁
        java.util.concurrent.Executors                //执行
        java.util.concurrent.ThreadPoolExector        //线程池
        java.util.concurrent.AtomicInteger            //原子量
        java.util.concurrent.BlockingQueue            //List
        java.util.concurrent.ConcurrentMap            //Map

    2、反射
        Class
        Method
        Field
        Constructor

    3、内省
        Introspector    
        BeanInfo        
        PropertyDescriptor

    4、代理
        Proxy
        接口集合
        目标对象
        InvocationHandler

JVM
----------------
    Java virtual machine.sand box,沙箱。

    [Runtime data area]
        运行时数据区,

    [method area]
        方法区,    被所有线程共享,存放的类的信息,如果出现并发加载
        类的时候,只有一个classloader进行加载,其他的等待。

    [heap]
        堆,被所有线程共享,存放的是对象和数组。
        堆内部划分成年轻代和年老代。
        年轻代内部划分成伊甸区和幸存区。
        幸存区又划分成幸存一区和幸存二区。
        堆
        |----年青代
                |----伊甸区
                |----幸存区(两个幸存区的目的是为了进行内存碎片整理。)
                        |----幸存一区
                        |----幸存二区

        |----年老代(至少保留512K空间)
            

        对象回收流程是从伊甸区创建,依次经过幸存一区(二区),
        到幸存二区(一区),最后达到年老代。

        java.lang.OutOfMemoryError: Java heap space,堆溢出
        //调整堆空间大小 , mx:最大值 ms:初始值
        java -Xmx4g -Xms4g

        使用jvisualvm考察jvm的内部结构。
        cmd -> jvisualvm ->工具  -> 插件 -> visual GC -> 安装.

        -Xms1g                //堆初始大小
        -Xmx1g                //堆最大值
        -Xmn1g                //年轻代大小
        -XX:NewSize=1g        //年轻代初始值
        -XX:MaxNewSize=1g    //年轻代最大值
        -XX:NewRatio=1        //设置年老代和年轻的倍数(比率),默认是2.
        -XX:SurvivorRatio=1    //设置伊甸区和单个幸存区的比率,默认值是6

        //调整堆空间
        java -Xmx500m -Xms500m -Xmn500m        //ok
        java -Xmx500m -Xms500m -Xmn0m        //not ok,年轻代至少 > 1.5m
        java -Xms1g -Xmx1g -XX:NewSize=750m -XX:MaxNewSize=750m -XX:SurvivorRatio=1


        [垃圾回收]
        对象被回收的条件是没有任意引用能够直接或间接到达该对象。
        full gc                //发生在old代gc。
        minor gc            //发生在young代。


        [通过jconsole软件考察内存结构]
        cmd -> jconsole

        [从堆角度对内存进行换分]
        1、堆内内存,年老代 + 年轻代
        2、非堆内存(non-heap),JVM - 堆,栈空间,方法区。
            metaspace(1.8改名,对应的是方法区) + 代码缓存区 + 压缩类空间。

        3、离堆内存(off-heap),JVM之外内存。
            在操作系统的内存中,但不在jvm中,java称之为直接访问。
            public static void main(String[] args) {
                //直接内存
                for(;;){
                    DirectBuffer buf = (DirectBuffer) ByteBuffer.allocateDirect(1024 * 1024 * 500);
                    buf.cleaner().clean();
                    //错误,因为离堆内存已经被回收掉了。
                    int n = ((ByteBuffer)buf).get(0);
                    System.out.println(n);
                    System.gc();
                }
            }
    [java stack]
        java栈
        先进后出
        对应一个线程,一个应用程序至少有一个栈,即主线程对应的栈(主栈).
        栈的操作有压栈(push)和弹栈(pop)。
        java栈中压入的stack frame,也叫方法帧(method frame).
        死递归容易导致栈溢出,可以通过jvm参数来进行设置。
        默认是1m。
        //调整栈空间
        java -Xss1m 

    [native method stack]
        本地方法栈,

    [program counter register]
        程序计数器,累计程序指令
原文地址:https://www.cnblogs.com/zyde/p/9225340.html