reference objects

看了很多的reference object相关文章,有些地方写得欠妥,不全,容易误导!


我来说说自己的看法:


1. 理论前提:对象的生命周期:
new --> reachable --> unreachable --> finalizable --> finalized --> reclaimed


2. weak reference:
检测到weak reachable后,jvm同时会干这么几件事:
1)擦除referent字段,(当然还有链上上其他referent字段)
2)referent原指向对象状态置为finalizable
3)之后会装入队列。
从中可以看出:
1)从队列里取出reference后,get()方法返回referent值,为null。
2)referent原指向对象的finalize()方法异步被调用(Finalizer线程)。
3)如果finalize()方法恶心的发布了强引用的this,不影响到队列相关的装入取出!


3. phantom reference:
满足两个条件才会被装入队列:
1)referent指向对象是finalized状态(要不然就进入reclaimed即物理释放了)。
2)phantom可达条件满足。
设计要领:
1)为了确保referent指向的对象可以被物理释放,get()方法重写为放回null。就是防止取回作为强引用!
2)referent指向对象不会被collector清除,除非references cleared。


从中可以看出:
1)队列中有reference后,指向对象的finalize()已经被调用,就差物理释放了。
2)references清除后,指向对象就可以物理释放了。
3)如果finalize()方法发布了this,是什么结果?对象又变成reachable了,不会被加入到队列中。这样就解决了恶心的finalize问题。
4)phantom目的很明显,应用代码可以依此追踪对象的生命周期-->finalized。
4. 假设我们需要跟踪对象a的生命周期,好做资源释放。
1)什么时候才是最佳的释放时机,a进入到unreachable或者finalized状态中?
2)如何监听这个状态?weak只有finalize()方法被调用(被动得知),或者轮训队列(主动得知)。phantom有个子类cleaner,可以在如队列之前,调用钩子(主动得知)。
3)为什么finalize不好?jvm规范没有规定finalizable-->finalize的具体时间,有可能很长。

4)phantom如队列之前,finalize会被调用,而且时间不定,可能很长,那这个方法好吗?jvm特殊对待重载finalize的对象,会调度到finialzer线程处理(较慢的方式)。所以,建议用phantom方式释放资源,finalize最好不要重载。示例代码参考DirectBuffer。



给份代码,哈哈,自己设计的:

package com.eastsoft.sample.java;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

/**
 * Created by MQ. EL on 2014/7/18.
 */
public abstract class JavaMain {

    public static MQ m;

    public static void main(String[] args) {
        MQ mq = new MQ();


        ReferenceQueue<MQ> rq = new ReferenceQueue();

        PhantomReference<MQ> pr = new PhantomReference<MQ>(mq, rq);

//        WeakReference<MQ> pr = new WeakReference<MQ>(mq, rq);

        System.out.println(mq);


        while (true) {
            mq = null;
            m = null;
            try {
                System.gc();
                Thread.sleep(1000);

                Reference<MQ> p = (Reference<MQ>) rq.poll();
                if (p != null) {
                    System.out.println(p);
                    Class<Reference> cl = Reference.class;

                    Field field = cl.getDeclaredField("referent");// cl.getField("referent");
                    field.setAccessible(true);
                    Object obj = field.get(p);
                    System.out.println(((MQ) obj).i);

                    MQ qq = (MQ) obj;
                    qq.i = 2;
                    m = qq;
                    pr = new PhantomReference<MQ>(qq, rq);
                    System.out.println(qq);
                } else
                    System.out.println("null");

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}


class MQ {
    public int i = 1;

    @Override
    public String toString() {
        return super.toString() + "MQ";
    }

    @Override
    public void finalize() {
        System.out.println("finish");
//        JavaMain.m = this;
    }
}

可以猜猜结果哦!超出你的想象,和其他的blog都说的不一样!


结论倒是很简单,只要对象没有物理释放,生命周期都可以转换。

对了针对referent这个变量,不是强引用,gc是特殊对待的一种引用!



<think>好的,我现在需要帮助用户解决在DataType.arxml文件中处理两个冗余的U_deg定义的问题。用户提到这两个定义可能有相同的名称和reference objects,想要合并或删除其中一个。首先,我需要回忆一下ARXML文件的结构和如何处理其中的冗余元素。 ARXML文件是基于AUTOSAR标准的XML格式,用于描述汽车软件架构。DataType通常定义在AR-PACKAGE中,每个数据类型可能有唯一的UUID。冗余的U_deg定义可能是因为重复导入或人为错误导致的。处理这种情况的步骤可能包括: 1. **确认冗余情况**:首先需要确认两个U_deg是否真的完全重复,包括名称、类型、reference objects和其他属性。有时候可能看起来相同,但某些属性如UUID或版本不同。 2. **备份文件**:在进行任何修改之前,必须备份原始的ARXML文件,避免操作失误导致数据丢失。 3. **使用工具检查**:如果有AUTOSAR工具(如Vector PREEvision、Elektrobit Tresos等),可以使用其内置的校验功能来检测重复项。这些工具通常能自动识别冗余并给出处理建议。 4. **手动编辑ARXML**:如果没有专用工具,可能需要手动编辑XML文件。需要找到两个U_deg的定义位置,检查它们的<SHORT-NAME>和引用对象是否一致。注意UUID(可能有<ADMIN-DATA>里的属性),如果不同,需要统一或删除一个。 5. **合并或删除操作**:如果确定要删除其中一个,需要确保没有其他元素引用它。如果有引用,需要将引用指向保留的U_deg。然后删除冗余的整个<DATA-TYPE>节点。 6. **验证修改**:修改后,使用工具或XML验证器检查ARXML的结构是否正确,确保没有破坏依赖关系。 可能遇到的问题包括:重复的UUID如何处理,其他元素对冗余U_deg的引用如何更新,以及如何确保合并后的数据类型在系统中正常工作。需要提醒用户仔细检查这些方面,或者使用版本控制以便回滚。 此外,用户可能没有提到的深层需求是希望保持ARXML文件的规范性和可维护性,避免未来再次出现冗余。因此,建议在团队协作或自动化流程中加入ARXML的校验步骤,防止重复定义。</think>### 在ARXML中处理冗余U_deg定义的方法 #### 1. **确认冗余性质** - **检查UUID唯一性**:每个AUTOSAR元素的`UUID`在`<ADMIN-DATA>`中唯一标识。若两个`U_deg`的`UUID`不同但名称和引用相同,需确认是否实际功能重复。 - **对比完整结构**:使用XML比对工具(如Beyond Compare)检查两个`U_deg`的完整XML节点,包括子元素(如`<SW-DATA-DEF-PROPS>`、`<CONSTRAINTS>`等)是否完全一致。 #### 2. **备份与版本控制** - 执行`git checkout -b fix_redundant_u_deg`创建新分支(若使用Git),或直接复制原始文件备份。 #### 3. **使用工具自动化处理** - **Vector PREEvision/Elektrobit Tresos**:通过工具内`Consistency Check`功能检测冗余,右键选择`Merge Duplicate Data Types`[^1]。 - **Python脚本辅助**(示例): ```python import xml.etree.ElementTree as ET tree = ET.parse('DataType.arxml') root = tree.getroot() # 查找所有U_deg定义 u_deg_list = root.findall(".//*[SHORT-NAME='U_deg']") if len(u_deg_list) > 1: # 保留第一个,删除后续重复项 for duplicate in u_deg_list[1:]: parent = duplicate.find('..') parent.remove(duplicate) tree.write('DataType_modified.arxml') ``` #### 4. **手动合并步骤** - **定位定义位置**: ```xml <!-- 示例冗余定义 --> <AR-PACKAGE UUID="..."> <ELEMENTS> <DATA-TYPE UUID="A"> <SHORT-NAME>U_deg</SHORT-NAME> <SW-DATA-DEF-PROPS>...</SW-DATA-DEF-PROPS> </DATA-TYPE> <DATA-TYPE UUID="B"> <!-- 冗余项 --> <SHORT-NAME>U_deg</SHORT-NAME> <SW-DATA-DEF-PROPS>...</SW-DATA-DEF-PROPS> </DATA-TYPE> </ELEMENTS> </AR-PACKAGE> ``` - **删除冗余节点**:保留`UUID="A"`的节点,删除`UUID="B"`的整个`<DATA-TYPE>`块。 - **更新引用**:全局搜索`REFERENCE-UUID="B"`,替换为`REFERENCE-UUID="A"`。 #### 5. **验证与测试** - **Schema校验**:使用`xmllint --schema AUTOSAR_4-2-2.xsd DataType_modified.arxml`确保文件符合AUTOSAR标准。 - **工具导入测试**:在Simulink或EB tresos中导入修改后的ARXML,检查是否有`Missing Reference`错误。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值