精华内容
下载资源
问答
  • 关于awk 中如何使用 if条件判断句

    千次阅读 2020-03-08 18:39:20
    文章目录 ... 首先,大家都知道 if 条件判断句 吧,这个就算不知道 也很好理解吧:无非就是条件成立则执行对应的代码、条件不成立则不执行!        在 awk 中,我们也是可以搭配 ...

    文章目录

     

    这个是我自己写的 全部关于 awk学习的目录导航 ,感兴趣的可以看看。

     


     
           首先,大家都知道 if 条件判断句 吧,这个就算不知道 也很好理解吧:无非就是条件成立则执行对应的代码、条件不成立则不执行!

           在 awk 中,我们也是可以搭配 if条件判断句 来使用:
    在这里插入图片描述
    千万要注意格式!!!!非常重要!!!!

            在编程语言中,if 还有 “if…else…” 或 “if…else if…else” 这样的语法,当然 awk 中也有这样的用法:

    首先看一下他们的语法吧:

    1、这是 “if…else…” 的语法
     
    if (条件)
    {
    语句1;
    语句2;

    }
    else
    {
    语句1;
    语句2;

    }
     
     
    2、这是 “if…else if…else” 的语法:
     
    if (条件1)
    {
    语句1;
    语句2;

    }
    else if(条件2)
    {
    语句1;
    语句2;

    }
    else
    {
    语句1;
    语句2;

    }

    举例:关于 “if…else…”
    这个语法的意思就是:if 条件匹配则执行…反正执行…
    在这里插入图片描述
    然后结合一下前面学过的 “格式化输出” 哈哈哈哈 学以致用嘛!
    在这里插入图片描述举例:关于 “if…else if…else”
    在这里插入图片描述
    这里本来是打算用截图的,但是字太小了,不方便大家查看,这里就使用代码块了:

    root@zhengzelin:~# 首先 你要知道 “if...else if...” 这个语法代表什么意思! 这里面包括几个条件?我们来看一个例子:
    
    root@zhengzelin:~# printf "%-10s\t%-10s\n" 姓名 年龄 张三 10 李四 20 王五 80 > aaa 
    root@zhengzelin:~# cat aaa 
    姓名    	年龄    
    张三    	10        
    李四    	20        
    王五    	80        
    
    root@zhengzelin:~# 使用 格式化 输出 到一个文件中 ,作为我们使用 if 语法的例子;
    说太多不如举一个例子,这样更加方便查看和理解:
    
    root@zhengzelin:~# awk 'BEGIN{FS="\t"} {if($2<=18) {printf "%-10s\t%-10s\n",$1," 是未成年"} else if($2>18 && $2<=60) {printf "%-10s\t%-10s\n",$1," 是成年人"} else{printf "%-10s\t%-10s\n",$1," 是老年人"}}' aaa
    姓名        	 是老年人     
    张三        	 是未成年     
    李四        	 是成年人     
    王五        	 是老年人     
    
    root@zhengzelin:~# 但是,你看这个输出结果,虽然是格式化的,但是第一排是什么鬼?姓名是老年人?这时候我们需要使用 NR 内置变量了:
    
    root@zhengzelin:~# awk 'BEGIN{FS="\t"} NR!=1 {if($2<=18) {printf "%-10s\t%-10s\n",$1," 是未成年"} else if($2>18 && $2<=60) {printf "%-10s\t%-10s\n",$1," 是成年人"} else{printf "%-10s\t%-10s\n",$1," 是老年人"}}' aaa
    张三        	 是未成年     
    李四        	 是成年人     
    王五        	 是老年人     
    
    如果你不懂 printf 格式化输出 或者 NR 等内置变量,建议您阅读前面的文章呢!
    本文章题目开头有 awk 学习导航,学习应该脚踏实地 一步一步来!
    
    

    虽然这样看的也不是很方便,但是最起码比那个图片要舒服!

    然后我再结合上篇学的 next 的用法:
    在这里插入图片描述
            使用 next 可以加快 脚本的执行速度!虽然结果出来了 ,但是 我也是对 next 理解的不是很清楚,如果哪位大佬有自己的见解,可以教一下我吗?

     
    上一篇:awk 中 next 的用法
    下一篇:awk 中的 循环语句:for、while…跳出循环:continue、break

    展开全文
  • 两个例子基本就了解了 简单一话: MD5可以为任何文件产生一个MD5值,好比是一个独一无二的“指纹”, 如果任何人对文件做了任何改动,其MD5值都会发生变化。 这样就能知道文件是否被篡改。 比如: MD5也可以对一段...

    MD5是干嘛用的?举两个例子基本就了解了
    简单一句话:
    MD5可以为任何文件产生一个MD5值,好比是一个独一无二的“指纹”,
    如果任何人对文件做了任何改动,其MD5值都会发生变化。
    这样就能知道文件是否被篡改。

    比如:
    MD5也可以对一段Message(字节串)产生fingerprint(指纹),以防止被“篡改”。
    举个具体的例子,将一段话写在一个叫 readme.txt文件中,
    并对这个readme.txt产生一个MD5的值并记录在案,
    然后这个文件传播给别人,
    别人如果修改了文件中的任何内容,
    再对这个文件重新计算MD5时就会发现:两个MD5值不相同。
    这样就可以判断文件被篡改了。这就是所谓的数字签名。

    再比如:
    在Unix系统中用户的密码是以MD5(或其它类似的算法)经Hash运算后存储在文件系统中。
    当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,
    然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。
    这样,系统在并不知道用户密码的明码的情况下也可以确定用户登录系统的合法性。
    还可以避免用户的密码被具有系统管理员权限的用户知道。
    这是因为:
    通过仅仅通过MD5值(128bit大整数)反推原始字符串是极其困难的。

    展开全文
  • 一、生成句法分析树把一话按照句法逻辑组织成一棵树,由人来做这件事是可行的,但是由机器来实现是不可思议的,然而算法世界就是这么神奇,把一个十分复杂的过程抽象成仅仅几步操作,甚至不足10行代码,就能让机器...

    一、生成句法分析树


    把一句话按照句法逻辑组织成一棵树,由人来做这件事是可行的,但是由机器来实现是不可思议的,然而算法世界就是这么神奇,把一个十分复杂的过程抽象成仅仅几步操作,甚至不足10行代码,就能让机器完成需要耗费人脑几十亿脑细胞的工作,本文我们来见识一下神奇的句法分析树生成算法 


     

    请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

    句法分析

    先来解释一下句法分析。句法分析分为句法结构分析和依存关系分析。

    句法结构分析也就是短语结构分析,比如提取出句子中的名次短语、动词短语等,最关键的是人可以通过经验来判断的短语结构,那么怎么由机器来判断呢?

    (有关依存关系分析的内容,具体可以看《依存句法以及语义依存分析》)

     

    句法分析树

    样子如下:

             -吃(v)-

    |                      |

    我(rr)            肉(n)

     

    句法结构分析基本方法

    分为基于规则的分析方法和基于统计的分析方法。基于规则的方法存在很多局限性,所以我们采取基于统计的方法,目前最成功的是基于概率上下文无关文法(PCFG)。基于PCFG分析需要有如下几个要素:终结符集合、非终结符集合、规则集。

    相对于先叙述理论再举实例的传统讲解方法,我更倾向于先给你展示一个简单的例子,先感受一下计算过程,然后再叙述理论,这样会更有趣。

    例子是这样的:我们的终结符集合是:∑={我, 吃, 肉,……},这个集合表示这三个字可以作为句法分析树的叶子节点,当然这个集合里还有很多很多的词

    我们的非终结符集合是:N={S, VP, ……},这个集合表示树的非页子节点,也就是连接多个节点表达某种关系的节点,这个集合里也是有很多元素

    我们的规则集:R={

    NN->我    0.5

    Vt->吃     1.0

    NN->肉   0.5

    VP->Vt NN    1.0

    S->NN VP 1.0

    ……

    }

    这里的句法规则符号可以参考词性标注,后面一列是模型训练出来的概率值,也就是在一个固定句法规则中NN的位置是“我”的概率是0.5,NN推出“肉”的概率是0.5,0.5+0.5=1,也就是左部相同的概率和一定是1。不知道你是否理解了这个规则的内涵

    再换一种方法解释一下,有一种句法规则是:

    S——|

    |        |

    NN    VP

              |——|

              Vt     NN

    其中NN的位置可能是“我”,也可能是“肉”,是“我”的概率是0.5,是“肉”的概率是0.5,两个概率和必为1。其中Vt的位置一定是“吃”,也就是概率是1.0……。这样一说是不是就理解了?

     

    规则集里实际上还有很多规则,只是列举出会用到的几个

    以上的∑、N、R都是经过机器学习训练出来的数据集及概率,具体训练方法下面我们会讲到

     

    那么如何根据以上的几个要素来生成句法分析树呢?

    (1)“我”

    词性是NN,推导概率是0.5,树的路径是“我”

    (2)“吃”

    词性是Vt,推导概率是1.0,树的路径是“吃”

    (3)“肉”

    词性是NN,概率是0.5,和Vt组合符合VP规则,推导概率是0.5*1.0*1.0=0.5,树的路径是“吃肉”

    NN和VP组合符合S规则,推导概率是0.5*0.5*1.0=0.25,树的路径是“我吃肉”

     

    所以最终的树结构是:

    S——|

    |        |

    NN    VP

    我      |——|

              Vt     NN

              吃     肉

     

    上面的例子是比较简单的,实际的句子会更复杂,但是都是通过这样的动态规划算法完成的

    提到动态规划算法,就少不了“选择”的过程,一句话的句法结构树可能有多种,我们只选择概率最大的那一种作为句子的最佳结构,这也是“基于概率”上下文无关文法的名字起源。

     

    上面的计算过程总结起来就是:设W={ω1ω2ω3……}表示一个句子,其中的ω表示一个词(word),利用动态规划算法计算非终结符A推导出W中子串ωiωi+1ωi+2……ωj的概率,假设概率为αij(A),那么有如下递归公式:

    αij(A)=P(A->ωi)

    αij(A)=∑∑P(A->BC)αik(B)α(k+1)j(C)

    以上两个式子好好理解一下其实就是上面“我吃肉”的计算过程

     

    以上过程理解了之后你一定会问,这里面最关键的的非终结符、终结符以及规则集是怎么得来的,概率又是怎么确定的?下面我们就来说明

     

     

    句法规则提取方法与PCFG的概率参数估计

    这部分就是机器学习的知识了,有关机器学习可以参考《机器学习教程

    首先我们需要大量的树库,也就是训练数据。然后我们把树库中的句法规则提取出来生成我们想要的结构形式,并进行合并、归纳等处理,最终得到上面∑、N、R的样子。其中的概率参数计算方法是这样的:

    先给定参数为一个随机初始值,然后采用EM迭代算法,不断训练数据,并计算每条规则使用次数作为最大似然计算得到概率的估值,这样不断迭代更新概率,最终得出的概率可以认为是符合最大似然估计的精确值。

     

    总结一下

    句法分析树生成算法是基于统计学习的原理,根据大量标注的语料库(树库),通过机器学习算法得出非终结符、终结符、规则集及其概率参数,然后利用动态规划算法生成每一句话的句法分析树,在句法分析树生成过程中如果遇到多种树结构,选择概率最大的那一种作为最佳句子结构


    二、从一个小例子来看词义消歧 


    日后再说这个成语到了当代可以说含义十分深刻,你懂的,但是如何让计算机懂得可能有两种含义的一个词到底是想表达哪个含义呢?这在自然语言处理中叫做词义消歧,从本节开始我们从基本的结构分析跨入语义分析,开始让计算机对语言做深层次的理解 


    词义消歧

    词义消歧是句子和篇章语义理解的基础,是必须解决的问题。任何一种语言都有大量具有多种含义的词汇,中文的“日”,英文的“bank”,法语的“prendre”……。

    词义消歧可以通过机器学习的方法来解决。谈到机器学习就会分成有监督和无监督的机器学习。词义消歧有监督的机器学习方法也就是分类算法,即判断词义所属的分类。词义消歧无监督的机器学习方法也就是聚类算法,把词义聚成多类,每一类是一种含义。

     

    有监督的词义消歧方法

    基于互信息的词义消歧方法

    这个方法的名字不好理解,但是原理却非常简单:用两种语言对照着看,比如:中文“打人”对应英文“beat a man”,而中文“打酱油”对应英文“buy some sauce”。这样就知道当上下文语境里有“人”的时候“打”的含义是beat,当上下文语境里有“酱油”的时候“打”的含义是buy。按照这种思路,基于大量中英文对照的语料库训练出来的模型就可以用来做词义消歧了,这种方法就叫做基于“互信息”的词义消歧方法。讲到“互信息”还要说一下它的起源,它来源于信息论,表达的是一个随机变量中包含另一个随机变量的信息量(也就是英文信息中包含中文信息的信息量),假设两个随机变量X、Y的概率分别是p(x), p(y),它们的联合分布概率是p(x,y),那么互信息计算公式是:

    I(X; Y) = ∑∑p(x,y)log(p(x,y)/(p(x)p(y)))

    以上公式是怎么推导出来的呢?比较简单,“互信息”可以理解为一个随机变量由于已知另一个随机变量而减少的不确定性(也就是理解中文时由于已知了英文的含义而让中文理解更确定了),因为“不确定性”就是熵所表达的含义,所以:

    I(X; Y) = H(X) - H(X|Y)

    等式后面经过不断推导就可以得出上面的公式,对具体推导过程感兴趣可以百度一下。

    那么我们在对语料不断迭代训练过程中I(X; Y)是不断减小的,算法终止的条件就是I(X; Y)不再减小。

    基于互信息的词义消歧方法自然对机器翻译系统的效果是最好的,但它的缺点是:双语语料有限,多种语言能识别出歧义的情况也是有限的(比如中英文同一个词都有歧义就不行了)。

     

    基于贝叶斯分类器的消歧方法

    提到贝叶斯那么一定少不了条件概率,这里的条件指的就是上下文语境这个条件,任何多义词的含义都是跟上下文语境相关的。假设语境(context)记作c,语义(semantic)记作s,多义词(word)记作w,那么我要计算的就是多义词w在语境c下具有语义s的概率,即:

    p(s|c)

    那么根据贝叶斯公式:

    p(s|c) = p(c|s)p(s)/p(c)

    我要计算的就是p(s|c)中s取某一个语义的最大概率,因为p(c)是既定的,所以只考虑分子的最大值:

    s的估计=max(p(c|s)p(s))

    因为语境c在自然语言处理中必须通过词来表达,也就是由多个v(词)组成,那么也就是计算:

    max(p(s)∏p(v|s))

    请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

    下面就是训练的过程了:

    p(s)表达的是多义词w的某个语义s的概率,可以统计大量语料通过最大似然估计求得:

    p(s) = N(s)/N(w)

    p(v|s)表达的是多义词w的某个语义s的条件下出现词v的概率,可以统计大量语料通过最大似然估计求得:

    p(v|s) = N(v, s)/N(s)

    训练出p(s)和p(v|s)之后我们对一个多义词w消歧的过程就是计算(p(c|s)p(s))的最大概率的过程

     

    无监督的词义消歧方法

    完全无监督的词义消歧是不可能的,因为没有标注是无法定义是什么词义的,但是可以通过无监督的方法来做词义辨识。无监督的词义辨识其实也是一种贝叶斯分类器,和上面讲到的贝叶斯分类器消歧方法不同在于:这里的参数估计不是基于有标注的训练预料,而是先随机初始化参数p(v|s),然后根据EM算法重新估计这个概率值,也就是对w的每一个上下文c计算p(c|s),这样可以得到真实数据的似然值,回过来再重新估计p(v|s),重新计算似然值,这样不断迭代不断更新模型参数,最终得到分类模型,可以对词进行分类,那么有歧义的词在不同语境中会被分到不同的类别里。

    仔细思考一下这种方法,其实是基于单语言的上下文向量的,那么我们进一步思考下一话题,如果一个新的语境没有训练模型中一样的向量怎么来识别语义?

    这里就涉及到向量相似性的概念了,我们可以通过计算两个向量之间夹角余弦值来比较相似性,即:

    cos(a,b) = ∑ab/sqrt(∑a^2∑b^2)

     

    机器人是怎么理解“日后再说”的

    回到最初的话题,怎么让机器人理解“日后再说”,这本质上是一个词义消歧的问题,假设我们利用无监督的方法来辨识这个词义,那么就让机器人“阅读”大量语料进行“学习”,生成语义辨识模型,这样当它听到这样一则对话时:

    有一位老嫖客去找小姐,小姐问他什么时候结账啊。嫖客说:“钱的事情日后再说。”就开始了,完事后,小姐对嫖客说:“给钱吧。”嫖客懵了,说:“不是说日后再说吗?”小姐说:“是啊,你现在不是已经日后了吗?”

    辨识了这里的“日后再说”的词义后,它会心的笑了


    三、语义角色标注

    浅层语义标注是行之有效的语言分析方法,基于语义角色的浅层分析方法可以描述句子中语义角色之间的关系,是语义分析的重要方法,也是篇章分析的基础,本节介绍基于机器学习的语义角色标注方法 

    语义角色

    举个栗子:“我昨天吃了一块肉”,按照常规理解“我吃肉”应该是句子的核心,但是对于机器来说“我吃肉”实际上已经丢失了非常多的重要信息,没有了时间,没有了数量。为了让机器记录并提取出这些重要信息,句子的核心并不是“我吃肉”,而是以谓词“吃”为核心的全部信息。

    “吃”是谓词,“我”是施事者,“肉”是受事者,“昨天”是事情发生的时间,“一块”是数量。语义角色标注就是要分析出这一些角色信息,从而可以让计算机提取出重要的结构化信息,来“理解”语言的含义。

     

    语义角色标注的基本方法

    语义角色标注需要依赖句法分析的结果进行,因为句法分析包括短语结构分析、浅层句法分析、依存关系分析,所以语义角色标注也分为:基于短语结构树的语义角色标注方法、基于浅层句法分析结果的语义角色标注方法、基于依存句法分析结果的语义角色标注方法。但无论哪种方法,过程都是:

    句法分析->候选论元剪除->论元识别->论元标注->语义角色标注结果

    其中论元剪除就是在较多候选项中去掉肯定不是论元的部分

    其中论元识别是一个二值分类问题,即:是论元和不是论元

    其中论元标注是一个多值分类问题

    下面分别针对三种方法分别说明这几个过程的具体方法

     

    基于短语结构树的语义角色标注方法

    短语结构树是这样的结构:

    S——|
    |        |
    NN    VP
    我      |——|
              Vt     NN
              吃     肉

    短语结构树里面已经表达了一种结构关系,因此语义角色标注的过程就是依赖于这个结构关系来设计的一种复杂策略,策略的内容随着语言结构的复杂而复杂化,因此我们举几个简单的策略来说明。

    首先我们分析论元剪除的策略:


    因为语义角色是以谓词为中心的,因此在短语结构树中我们也以谓词所在的节点为中心,先平行分析,比如这里的“吃”是谓词,和他并列的是“肉”,明显“肉”是受事者,那么设计什么样的策略能使得它成为候选论元呢?我们知道如果“肉”存在一个短语结构的话,那么一定会多处一个树分支,那么“肉”和“吃”一定不会在树的同一层,因此我们设计这样的策略来保证“肉”被选为候选论元:如果当前节点的兄弟节点和当前节点不是句法结构的并列关系,那么将它作为候选论元。当然还有其他策略不需要记得很清楚,现用现查就行了,但它的精髓就是基于短语结构树的结构特点来设计策略的。

    然后就是论元识别过程了。论元识别是一个二值分类问题,因此一定是基于标注的语料库做机器学习的,机器学习的二值分类方法都是固定的,唯一的区别就是特征的设计,这里面一般设计如下特征效果比较好:谓词本身、短语结构树路径、短语类型、论元在谓词的位置、谓词语态、论元中心词、从属类别、论元第一个词和最后一个词、组合特征。

    论元识别之后就是论元标注过程了。这又是一个利用机器学习的多值分类器进行的,具体方法不再赘述。

     

    基于依存句法分析结果和基于语块的语义角色标注方法

    这两种语义角色标注方法和基于短语结构树的语义角色标注方法的主要区别在于论元剪除的过程,原因就是他们基于的句法结构不同。

    基于依存句法分析结果的语义角色标注方法会基于依存句法直接提取出谓词-论元关系,这和依存关系的表述是很接近的,因此剪除策略的设计也就比较简单:以谓词作为当前节点,当前节点所有子节点都是候选论元,将当前节点的父节点作为当前节点重复以上过程直至到根节点为止。

    基于依存句法分析结果的语义角色标注方法中的论元识别算法的特征设计也稍有不同,多了有关父子节点的一些特征。

    有了以上几种语义角色标注方法一定会各有优缺点,因此就有人想到了多种方法相融合的方法,融合的方式可以是:加权求和、插值……,最终效果肯定是更好,就不多说了。

    展开全文
  • JVM如何判断对象能否被回收

    万次阅读 多人点赞 2019-12-16 16:11:57
    来,例子来理解,比如现在有两个对象objectA和objectB都有字段instance,赋值让objectA.instance = objectB, objectB.instance = objectA,除此之外没有任何其他引用,实际上这两个对象已经不可能再被访问了,...

    目录

    •写在前面

    •对象的创建

    •引用计数算法

    •可达性分析算法

    •引用

    •不可达必须“死”?

    •最后


    •写在前面

    说起Java和C++,很容易想到让人疯狂的指针,Java使用了内存动态分配和垃圾回收技术,让我们从C++的各种指针问题中摆脱出来,更加专心于业务逻辑,不过如果我们需要深入了解java的JVM相关原理,我们必须要面对这些东西,深入了解JVM在内存动态分配和垃圾回收技术的原理知识,这篇文章就是来做一个先导,在jvm进行垃圾回收之前,它必须要知道回收的对象是否已“死”,这样才能保证程序的正常稳定。

    •对象的创建

    我们将回收对象前,先讲讲在虚拟机上,对象是怎么被创建的。在我们编写代码的角度(语言层面)来看,我们创建一个对象实例,只需要使用new关键词就完事儿了,很简单,不过你享受的简单是因为虚拟机帮你承受了所有繁琐的工作,那虚拟机是怎么工作创建一个对象的呢?

    当虚拟机遇到new指令时,首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用(没有类,创建个锤子的对象),并且检查这个符号引用代表的类是否已被加载、解析和初始化过,如果没有,那必须要执行相应的类加载过程。这是第一步,在类加载检查过后,接下来虚拟机将为新生对象分配内存,对象所需的内存大小在类加载完成后便已经完全确定了(这里插一句,如何确定的?这就和对象的内存布局有关了,对象在内存中的布局可以分为3个区域,分别是对象头、实例数据和对齐填充,对象头里面存的是对象自身的运行时数据,比如哈希码、GC分代年龄、锁状态、线程持有的锁、偏向线程ID等等之类的信息,也就是和储存数据无关的额外内存空间,按道理这一块空间应该是固定的,不过在设计上还是被弄成了非固定的数据结构,这样更具不同的类节省空间,不深入不然扯不完,想要可以看另外一篇文章。接下来实例数据就是对象真正储存的有效信息,也是程序代码中所定义的各种类型的字段内容。最后一个对齐填充,顾名思义就是填补空间,因为以HotSpotVM为例,对象的大小必须是8字节的整数倍,所以就靠这个补全),给对象分配空间的任务相当于把一块确定大小的内存从Java堆中划分出来(为啥可以看我另一篇文章,运行时数据区)。

    划分的时候会出现两种情况,第一种就是java堆中的内存是绝对规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间的一边移动对象大小相等的距离,这种分配方式就是“指针碰撞”。第二种情况就是空间不规整,也就是已使用的内存和空闲内存相互交错,这个时候指针碰撞起不来作用,那么这个时候虚拟机必须维护一个列表,记录哪些内存可用,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新相关内存信息,这种方式叫做“空闲列表”。因为创建对象非常频繁,所以会涉及到并发的时候,会出现一个叫做“本地线程分配缓冲”的概念,我这里也不深入,自己去查,哈哈哈。空间分配完成之后,虚拟机需要分配到的内存空间都进行初始化为零值(注意不包括对象头),这样就保证对象的实例字段在java代码中可以不赋初始值就直接使用。最后虚拟机要对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息,对象的哈希码、对象的GC分代等信息。到此,对于虚拟机来说,对象创建完毕。

    •引用计数算法

    引用计数是一个很好理解的概念,就是给对象添加一个引用计数器,每当有一个地方引用这个对象时,计数器值加1,每当一个引用失效时,计数器减1,任何时刻计数器为0的对象就是不可能再被使用的。是不是很好理解,而且判定对象是否可用效率很高,在大部分时候它是一个很不错的算法,不过要注意,是大部分时候。在java虚拟机中,并没有使用这个算法来管理内存,其中最主要的原因就是它很难解决对象之间循环引用的问题。来,举个例子来理解,比如现在有两个对象objectA和objectB都有字段instance,赋值让objectA.instance = objectB, objectB.instance = objectA,除此之外没有任何其他引用,实际上这两个对象已经不可能再被访问了,但是因为它们两个互相引用这对方,导致它们的引用计数不为0,则算法不能通知GC收集器回收它们。所以这种算法不适合在虚拟机上使用,但是并不是说这个算法很垃圾,它可是在其他方面有很多著名的案例。

    •可达性分析算法

    JVM的主流实现是可达性分析,可达性分析在概念上其实也不难理解,它的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时(图论里面专业一点来说,就是从GC Roots到这个对象不可达),则证明对象是不可用的,大致可以像下图理解。

    那么哪些对象可以作为GC Roots对象呢?在java中大致有如下几种:

    •虚拟机栈(栈帧中的本地变量表)中引用的对象;(不知道栈帧是啥的看我另一篇文章,运行时数据区

    •方法区中类静态属性引用的对象;

    •方法区常量引用的对象;

    •本地方法栈中JNI(即一般说的Native方法)引用的对象;

    •引用

    引用是啥?搞过C++的我们第一反应就会回答,如果reference类型的数据中储存的数值代表的是另一个内存的起始地址,就称这块内存代表着一个引用。这种定义没有错,不过太狭隘了,一个对象在这种定义下只能被引用或者没有被引用两种状态,显然在回收中不足以应付碰到的情况。所以,java对引用概念进行了扩充,将引用分为强引用、软引用、弱引用、虚引用四种,这四种引用强度一次逐渐减弱。

    •强引用,就是指在程序代码之中普遍存在的,类似A a = new A()这样的引用,只要强引用存在,垃圾回收器就不会回收掉被引用的对象;

    •软引用,用来描述一些还有用但并非必须的对象,对于软引用的对象,在系统将要发生内存溢出异常之前,将会把这些对象列进回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会出现内存溢出异常;

    •弱引用,也是用来描述非必需的对象,但是它的强度比软引用更弱,被弱引用关联的对象只能生存到下一次回收发生之前,当垃圾回收器工作时,无论当前内存是否足够,都会回收掉;

    •虚引用,它是最弱的一种引用关系,一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用取得一个对象实例、为一个对象设置引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。

    •不可达必须“死”?

    其实在实际中,就算在可达性分析算法中不可达的对象,也并非一定会回收,这个时候不可达的对象暂时处于暂缓的阶段,一个对象要真正宣告死亡,至少要经历两次标记的过程,当对象进行可达性分析而不可达时,它会被第一次标记并且进行一次筛选,筛选条件是这个对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被调用过了,虚拟机将会把这两种情况视为没有必要执行finalize。当对象被判定有必要执行finalize时,对象将会被放置在一个叫做F-Queue的队列中,并在稍后的一个由虚拟机自动建立的、优先级低的一个Finalizer线程去出发这些对象的finalize(要注意的是,虚拟机并不承诺会等待这些对象finalize方法执行结束,这是因为如果一个对象的finalize方法执行缓慢、或者发生死循环,将导致F-Queue队列其他对象处于永久等待,甚至导致内存回收系统崩溃)。finalize是对象逃脱回收的最后一次机会,GC会将F-Queue中的对象进行第二次小规模的标记,如果对象在finalize中重新和引用链连上了,那么就被移出回收集合,没有逃脱则将会被回收(要记住哦,对象的finalize只能被执行一次,也就是说当对象通过finalize逃脱回收之后,下一次如果再被可达性分析标记,那么就逃不了了)。

    •最后

    其实很多时候我们谈论回收都在java堆上进行的,上面对象实例都是在java堆上进行的,很少谈及方法区的回收,因为方法区(一般被称为永久代)中的回收条件很苛刻,比如在java堆上进行回收可以达到70%-95%的空间,在方法区却低很低,但并不代表方法区不能有垃圾回收,Java虚拟机规范中,只是说可以不要求在方法区实现回收机制。

    展开全文
  • 测试用例模板和例子

    万次阅读 2018-11-09 16:25:09
    这个例子可能有些极端,但测试用例与需求和设计不同步的情况在实际开发过程中确是屡见不鲜的,测试用例文档是“活的”文档,这一点应该被测试工程师牢记。   4、测试用例不应该包含实际的数据; 测试用例...
  • 非常全面的贝叶斯网络介绍 非常多的例子说明

    万次阅读 多人点赞 2014-05-26 16:10:36
    这是一篇关于贝叶斯方法的科普文,我会尽量少用公式,多用平白的语言叙述,多实际例子。更严格的公式和计算我会在相应的地方注明参考资料。贝叶斯方法被证明是非常 general 且强大的推理框架,文中你会看到很多...
  • 贝叶斯从浅入深详细解析,详细例子解释

    万次阅读 多人点赞 2013-06-24 11:38:31
    这是一篇关于贝叶斯方法的科普文,我会尽量少用公式,多用平白的语言叙述,多实际例子。更严格的公式和计算我会在相应的地方注明参考资料。贝叶斯方法被证明是非常 general 且强大的推理框架,文中你会看到很多...
  • 最经典的java 23种设计模式及具体例子

    万次阅读 多人点赞 2016-07-10 09:43:50
    最经典的java 23种设计模式及具体例子
  • VC API常用函数简单例子大全

    千次阅读 2012-10-22 11:31:06
    VC API常用函数简单例子大全 http://hi.baidu.com/tag/vc%20api%E5%87%BD%E6%95%B0/feeds   系统API查询 http://www.vbgood.com/api.html http://hi.baidu.com/3582077/item/9cc3483b581f53c5392ffae3 第一...
  • 架构设计 例子和实践 系统设计说明书(架构、概要、详细)目录结构演进架构中的领域驱动设计Web架构设计经验分享软件架构设计从MVC框架看MVC架构的设计领域驱动设计(Domain Driven Design)参考架构详解关于垂直切分...
  • 闲聊几

    千次阅读 2017-08-28 14:39:24
    一个简单的例子,假如你抓住小偷在偷你的东西,大概不会因为他拿“存在即合理”这话为自己辩解而放他走,存在小偷盗窃现象的合理是合乎什么道理呢?小偷的贪欲,想要不劳而获。因为他想要不劳而获获得你的某些...
  • Windows API常用函数简单例子大全

    千次阅读 2013-09-15 09:53:59
    作用可大了,因为很多操作窗口的函数,都需要窗口句柄作参数,如移动、改变窗口大小的MoveWindow函数,在这里例子,大家就更能体会到这个FindWindow的用法、用处。 FindWindow例子:已知一个窗口名称,写...
  • TensorFlow入门1-CNN网络及MNIST例子讲解

    千次阅读 多人点赞 2018-05-04 07:50:39
    我之前做了一个判断一张图片是否是自选股截图的程序,自选股截图指的是下面这种图片。 首先我会去看这种图片有什么特征,很明显,自选股截图上面有规则的红绿方块,而其他图片是没有的。那么在程序中,我首先...
  • C++内存管理(超长,例子很详细,排版很好)

    万次阅读 多人点赞 2018-04-02 13:56:49
     首先,我们一个例子: void f() { int* p=new int[5]; }  这条短短的一话就包含了堆与栈,看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这话的意思就是:...
  • decode(类型, '类型1', '值1', '类型2', '值2', '其它') 方法二:使用case语句 最后希望文章对你有所帮助,主要讲述了使用DECODE函数和CASE判断多值问题,当然如果多个类型也是可以判断并多指输出的,但建议通常...
  • VC API常用函数简单例子大全(1-89)

    千次阅读 2013-10-18 23:11:04
    尝鲜 code奸我千百遍,我待code如初见 ...VC API常用函数简单例子大全(1-89) 第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄 函数的定义:HWND WINAPI
  • 或的作用一个例子,我明早上吃包子或者吃米粉。这一话表示我只吃其中一样,两个都行;而或运算也是这个意思,或运算符“||”左右两边有一个对那么算对了。这个时候我输入6666也正确,输入10也正确。结果如下: ...
  • 多个if判断和if-else-if判断的区别

    千次阅读 2019-05-20 10:27:22
    拿二维矩阵来例子 public class Solution { public boolean Find(int target, int [][] array) { int rows = 0; int cols = array[0].length-1; while(rows <= array.length-1 &&...
  • python判断对象是否为None

    万次阅读 2017-08-15 11:40:06
    代码中经常会有变量是否为None的判断,有三种主要的写法: 第一种是`if x is None`; 第二种是 `if not x:`; 第三种是`if not x is None`(这这样理解更清晰`if not (x is None)`) 。 如果你觉得这样写没啥...
  • PHP中如何判断数组是否为空

    千次阅读 2015-07-18 14:34:08
    PHP判断数组为空之一、for循环 最简单也是最直接的方法,用for循环来遍历数组。对于已知维数的数组可以判断,但如果是未知的多维数组,该怎么办? PHP判断数组为空之二、...例子: $arr= array(array(),array
  • 例子: H(s)=as/(bs+c) 分子上有“高次”,所以是高通。 这里的“高次”是这个意思: 分母上有s的0次和1次,分子是s的1次,所以是较高的那个,简称“高次”。 H(s)=a/(bs+c) 分子上有“低次”,所以是低通...
  • PHP 判断常量,变量和函数是否存在

    千次阅读 2009-04-25 06:39:00
    如果你看懂了上面一话,那么接下来都是废话,PHP手册...还是几个例子吧:* 判断常量是否存在*/if (defined(MYCONSTANT)) {echo MYCONSTANT;}//判断变量是否存在if (isset($myvar)) {echo "存在变量$myvar.";}//判断
  • 例子,对于下面的这个有向图的随机变量(注意,这个图我画的还是比较广义的): 应该这样表示他们的联合概率: 应该很好理解吧。 2. 无向图 对于无向图,我看资料一般就指马尔科夫网络(注意,这个图我画的也是比较...
  • 根据系统函数快速判断滤波器...例子: H(s)=as/(bs+c) 分子上百有“高次”,所以是高通。 这里的“高次”是这个意思: 分母上有s的0次和1次,分子是s的1次,所以是较高的那个,简称“高次”。 H(s)=a/(bs+c) 分子上
  • 因果关系的判断

    千次阅读 2020-06-29 15:56:45
    最简单的方法是从相关性,先后顺序,排除干扰因素三个方面下手 ...所以可以看出,判断因果其实是个逻辑过程。 ----------------------------------------------------------------------------------------------
  • 初中英语语法(018)-间接疑问

    千次阅读 2019-04-27 22:08:08
    间接疑问是一种从句的形式,例子就明白了: Who is that tall girl? - 那个高个子女孩是谁? 和以前我们学过的所有疑问一样,这就是直接疑问。 He want to know who that tall girl is. - 他想知道那个...
  • 个简单的例子,比如说判断在当前目录下判断一个文件script1.sh是否存在,那么根据test使用的语法,可写成如下: test -e script1.sh 如果存在的话那么返回的值是1,于是我们结合 && 以及 || 逻辑运算可构造:  ...
  • 目录 一、可以用三种方式解决子串问题:函数strstr、...先几个例子来说明一下什么样的字符串可以称作子串(区分大小写,假设字符串数组长度为20): 令str1[20]="dou LUO da lu"; 1.str2[20]="da l";是子串; 2.
  • 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这话只适用大部分线性表,而不是全部。比如,循环链表逻辑层次上也是一种线性表(存储层次...
  • Python十大装B语法

    万次阅读 多人点赞 2019-11-01 14:29:21
    匿名函数一般不会单独使用,而是配合其他方法,为其他方法提供内置的算法或判断条件。比如,使用排序函数sorted对多维数组或者字典排序时,就可以指定排序规则。 >> > a = [ { 'name' : 'B' , 'age' : 50 } ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 84,206
精华内容 33,682
关键字:

判断句举例子