zoukankan      html  css  js  c++  java
  • jvm

    什么是虚拟机:虚拟出来的一种机器

             -----------字节码指令集

           ----------------内存管理方法:堆 栈  方法区

    回收算法

      引用计数器算法(reference count):从被加载就记录被引用次数,每次使用后计数减一,直至被减为0后被回收。能被引用的不会被回收。弊端:不能定义循环引用,相互引用但不被利用他们都是垃圾(无法回收)。

       可达性算法(root searching): 从主入口根部能被引用使用到的都被记入。从根部理不到的就等着被回收。

      回收方法:

           标记清除(Mark-Sweep)是垃圾的被标记,之后被回收。算法简单。缺点:造成内存碎片化,内存地址不连续,导致下次分配内存给某个对象。内存加起来够,实际放不下。

          拷贝(Copying):无论多大内存,被分为2分,其中被使用的一份需要被回收的时候,整个直接复制过去排列放好。确定,浪费空间,没被使用的内存也被处理掉

          标记压缩(Mark-Compact):把垃圾标记出来,一边使用一边压缩。缺点:效率底,多线程需要使用锁同步

    产生垃圾:进行标记,垃圾太多多线程标记,还是太多,并发标记,三色标记(cms算法)

    查看占用内存最多的进程指令:jps

    jinfo 56860

    然后会查到一个进程,使用jmap -histo [进程号]          查看使用占用内存的类

     

     

    监控内存的工具:arthas

    wget https://alibaba.github.io/arthas/arthas-boot.jar
    java -jar arthas-boot.jar     这时候需要选择你想要诊断的进程,回车即可
    如果不知道某个java进程的详情,可以使用
    jps -mlVv 或 ps -ef| grep java
    help——查看命令帮助信息
    cat——打印文件内容,和linux里的cat命令类似
    pwd——返回当前的工作目录,和linux命令类似
    cls——清空当前屏幕区域
    session——查看当前会话的信息
    reset——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
    version——输出当前目标 Java 进程所加载的 Arthas 版本号
    history——打印命令历史
    quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
    shutdown——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
    keymap——Arthas快捷键列表及自定义快捷键

    输入dashboard,按回车/enter,会展示当前进程的信息,按ctrl+c可以中断执行。
    thread线程
    thread 1会打印线程ID 1的栈,通常是main函数的线程
    jad demo.MathGame
    如果只是退出当前的连接,可以用quit或者exit命令。Attach到目标进程上的arthas还会继续运行,端口会保持开放,下次连接时可以直接连接上
     https://arthas.aliyun.com/doc/quick-start.html

     

     

    Java垃圾回收机制——finallize()

        其实了解JAVA的人,都知道JAVA的GC机制是其的一大优点,它令程序员不需要主动去考虑内存溢出和垃圾回收的问题,不像c++具有显式的析构函数对整个对象进行内存清理以及需要调用delete才可以进行显示的销毁对象。

    当然也有存在特殊的情况:假定你的对象(并非使用new方法)获得了一块“特殊”的内存区域,由于垃圾回收器只知道那些显示地经由new分配的内存空间,所以它不知道该如何释放这块“特殊”的内存区域,那么这个时候java允许在类中定义一个由finalize()方法。

    对于上面这个问题,首先了解一下什么是“特殊”的内存区域?

    由于在分配内存的时候可能采用了类似 C语言的做法,而非JAVA的通常new做法。这种情况主要发生在native method中,比如native method调用了C/C++方法malloc()函数系列来分配存储空间,但是除非调用free()函数,否则这些内存空间将不会得到释放,那么这个时候就可能造成内存泄漏。但是由于free()方法是在C/C++中的函数,所以finalize()中可以用本地方法来调用它。以释放这些“特殊”的内存空间。

    另外finalize()方法还可以用作这样的用途:因为在JAVA中并没有提够像“析构”函数或者类似概念的函数,要做一些类似清理工作的时候,必须自己动手创建一个执行清理工作的普通方法,也就是override Object这个类中的finalize()方法。例如,假设某一个对象在创建过程中会将自己绘制到屏幕上,如果不是明确地从屏幕上将其擦出,它可能永远都不会被清理。如果在finalize()加入某一种擦除功能,当GC工作时,finalize()得到了调用,图像就会被擦除。要是GC没有发生,那么这个图像就会被一直保存下来。

    其次,了解一下finalize()方法的工作原理:一旦垃圾回收器准备好释放对象占用的存储空间,首先会去调用finalize()方法进行一些必要的清理工作。只有到下一次再进行垃圾回收动作的时候,才会真正释放这个对象所占用的内存空间。

    最后,必须一定要正视一个问题:finalize()并不是代替了delete()方法,来作为清理内存的方法。为什么呢?在C++中所有的对象运用delete()一定会被销毁,而JAVA里的对象并非总会被垃圾回收器回收。In another word, 1 对象可能不被垃圾回收,2 垃圾回收并不等于“析构”,3 垃圾回收只与内存有关。也就是说,并不是如果一个对象不再被使用,是不是要在finalize()中释放这个对象中含有的其它对象呢?不是的。因为无论对象是如何创建的,垃圾回收器都会负责释放那些对象占有的内存。

      

    一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰
  • 相关阅读:
    分布式事务之可靠消息
    分布式事务之本地消息表
    分布式事务
    数据库之 事务
    WePY开发小程序(二):项目入口及注册页面、组件
    WePY开发小程序(一):入门
    vue学习笔记-事件监听
    vue学习笔记-列表渲染
    vue学习笔记-缩写
    vue学习笔记-常用指令
  • 原文地址:https://www.cnblogs.com/wangbiaohistory/p/14545243.html
Copyright © 2011-2022 走看看