Local Reference and Global Reference

 本文来自:IBM Knowledge Center  
 https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.lnx.71.doc/diag/understanding/jni_transitions_j2j_n2n.html?lang=en


Local references are scoped to their creating stack frame and thread, and automatically deleted when their creating stack frame returns. Global references allow native code to promote a local reference into a form usable by native code in any thread attached to the JVM.
Global references and memory leaks



JNI transitions

To understand JNI local reference management and the GC, you must understand the context of a running thread attached to the JVM.

Every thread has a runtime stack that includes a frame for each method call.

From a GC perspective, every stack establishes a thread-specific "root set" including the union of all JNI local references in the stack.


Each method call in a running VM adds (pushes) a frame onto the stack, just as every return removes (pops) a frame.

Each call point in a running stack can be characterized as one of the following types:

Java to Java (J2J)
Native to Native (N2N)
Java to Native (J2N)
Native to Java (N2J)

.


J2J and N2N transitions
Because object references do not change form as part of J2J or N2N transitions, J2J and N2N transitions do not affect JNI local reference management.



N2J transitions
For native code to call Java code (N2J) in the current thread, the thread must first be attached to the JVM in the current process.
Every N2J call that passes object references must have obtained them using JNI, therefore they are either valid local or global JNI refs. Any object references returned from the call are JNI local references.


J2N calls
The JVM must ensure that objects passed as parameters from Java? to the native method and any new objects created by the native code remain reachable by the GC.
To handle the GC requirements, the JVM allocates a small region of specialized storage called a local reference root set.

J2N calls
The JVM must ensure that objects passed as parameters from Java? to the native method and any new objects created by the native code remain reachable by the GC.
To handle the GC requirements, the JVM allocates a small region of specialized storage called a local reference root set.

A local reference root set is created when:

A thread is first attached to the JVM (the outermost root set of the thread).
Each J2N transition occurs.
The JVM initializes the root set created for a J2N transition with:

A local reference to the caller's object or class.
A local reference to each object passed as a parameter to the native method.

.


New local references created in native code are added to this J2N root set, unless you create a new local frame using the PushLocalFrame JNI function.


The default root set is large enough to contain 16 local references per J2N transition. The -Xcheck:jni command-line option causes the JVM to monitor JNI usage.

hen -Xcheck:jni is used, the JVM writes a warning message when more than 16 local references are required at run time.
If you receive this warning message, use one of the following JNI functions to manage local references more explicitly:

NewLocalRef
DeleteLocalRef
PushLocalFrame
PopLocalFrame
EnsureLocalCapacity




为了理解JNI local reference 管理和GC垃圾收集,必须了解一个在JVM中一个运行线程的上下文。

当一个方法调用时,该线程就会创建一个包含“帧”的运行时栈 。 从GC来讲,每一个栈都建立一个线程 “根集合”。“根集合”包括在该栈中的所有jni local reference.


在一个运行中的VM来讲,每次调用方法都会在栈中增加一“帧”,当方法返回时都从栈中移除一“帧”。每次调用类型如下 :

Java to Java (J2J)
Native to Native (N2N)
Java to Native (J2N)
Native to Java (N2J)


J2J 和N2N 交换:因为J2J 和N2N在交换时,对象的引用不会发生改变,所有J2J和N2N交换不会影响到JNI local reference的管理。


N2J交换:在当前线程中,native code调用java code方法(N2J),当每次N2J调用时,必须使用JNI方法来获取引用来传递到java Code中,所以,即可以存在local reference 或者global reference . 任何通过 JNI方法返回的对象引用都是JNI local reference .

J2N交换: java 虚拟机必须保证每一个由java code中的对象作为参数传递到native code 和任何通过native  code创建的新对象都必须可以通过GC是可以到达的。

为了满足GC的需求,java虚拟机分配一个很小的特殊区域来存储  local  reference  set 。

一个local  reference set在如下情况下会被创建:

1-当一个线程第一次连接到JVM

2-每一次J2N 函数调用

JVM为了J2N交换初始化:1 -一个对于调用对象或者类的local reference  2-每一个当做参传递到native code方法中的local reference.

通过native code创建的每一个新local  reference 都被增加到J2N root set中。默认的local reference 最大存储16个local reference.


<think>好的,我现在需要解决用户提到的Oracle同步视图报错“illegal reference to remote database”的问题。首先,我得先理解这个错误的原因。根据我的知识,Oracle中当创建视图或者执行某些跨数据库操作时,可能会遇到权限或配置的问题。用户提到的错误信息通常与数据库链接(DB Link)的权限有关,或者视图定义中直接引用了远程对象而没有正确使用DB Link。 接下来,我应该分步骤思考可能的解决方案。首先,确认用户是否创建了数据库链接,并且该链接是否有效。如果数据库链接不存在或者名称拼写错误,视图就无法正确访问远程数据库,导致这个错误。此外,即使存在DB Link,用户可能没有足够的权限访问远程表,或者视图的定义中未正确使用DB Link语法。 然后,我需要考虑视图的创建方式。用户可能在视图的SQL语句中直接使用了远程表的名称,比如SELECT * FROM remote_table@dblink_name,但如果没有正确引用或者权限不足,就会报错。此外,权限问题可能包括用户没有授予必要的SELECT权限,或者数据库链接没有使用正确的用户认证。 另一个可能的原因是Oracle的跨数据库操作限制。某些情况下,Oracle不允许直接在视图中引用远程对象,除非使用特定的方法,比如物化视图或者使用本地同义词。用户可能需要检查是否应该使用物化视图而不是普通视图,或者是否需要在本地创建同义词来引用远程对象。 我还应该考虑Oracle的版本和配置,不同版本可能有不同的安全策略或默认设置,比如在较新的版本中,跨DB Link的访问可能需要更明确的权限设置。此外,检查网络配置,如TNSNAMES.ORA文件是否正确配置了远程数据库的连接信息,确保数据库链接可以正常通信。 最后,可能需要指导用户一步步排查问题,从验证数据库链接开始,检查权限,确认视图定义是否正确,再到考虑使用同义词或物化视图作为替代方案。同时,提醒用户查看具体的错误堆栈信息,以便更精准地定位问题所在。</think>### Oracle同步视图报错“illegl reference to remote database”的解决方案 #### 错误原因 当在Oracle中创建视图时,若直接引用远程数据库的表(通过DB Link)但未正确处理权限或语法,会触发此错误。常见原因包括: 1. **权限不足**:当前用户无权限访问远程数据库的表。 2. **DB Link配置错误**:数据库链接名称拼写错误、未生效或权限问题。 3. **视图定义语法问题**:未正确使用DB Link语法或尝试跨库操作受限制。 4. **Oracle限制**:普通视图可能不支持直接引用远程对象,需使用物化视图(Materialized View)或本地同义词。 --- #### 逐步排查与解决 ##### **步骤1:检查数据库链接(DB Link)** 1. **确认DB Link存在且有效**: ```sql SELECT * FROM ALL_DB_LINKS WHERE OWNER = '当前用户'; ``` 若未查询到记录,需先创建DB Link: ```sql CREATE DATABASE LINK dblink_name CONNECT TO remote_user IDENTIFIED BY remote_password USING 'remote_tns_entry'; ``` 2. **测试DB Link连通性**: ```sql SELECT * FROM dual@dblink_name; ``` 若报错(如ORA-12154),检查TNSNAMES.ORA配置或网络连接。 --- ##### **步骤2:检查视图定义语法** 视图中引用远程表时,**必须显式添加DB Link后缀**: ```sql CREATE VIEW local_view AS SELECT * FROM remote_table@dblink_name; -- 正确 ``` 若省略`@dblink_name`,会报错“illegal reference”。 --- ##### **步骤3:验证权限** 1. **本地用户权限**: - 需具备`CREATE VIEW`权限。 - 需被授权访问远程表: ```sql GRANT SELECT ON remote_table TO remote_user; ``` 2. **DB Link权限**: - 若DB Link使用固定用户(如`CONNECT TO ... IDENTIFIED BY ...`),确保远程用户有`SELECT`权限。 - 若使用当前用户权限(`CONNECT TO CURRENT_USER`),需配置本地和远程用户的权限映射。 --- ##### **步骤4:使用同义词简化引用** 为远程表创建本地同义词,避免在视图中硬编码DB Link: ```sql CREATE SYNONYM local_synonym FOR remote_table@dblink_name; CREATE VIEW local_view AS SELECT * FROM local_synonym; ``` --- ##### **步骤5:考虑使用物化视图** 若普通视图无法满足需求(如需要定期同步数据),改用物化视图: ```sql CREATE MATERIALIZED VIEW mv_name REFRESH COMPLETE START WITH SYSDATE NEXT SYSDATE + 1 AS SELECT * FROM remote_table@dblink_name; ``` --- ##### **步骤6:检查Oracle版本及配置** - **版本限制**:Oracle Standard Edition可能不支持某些高级跨库功能。 - **参数设置**:确认`GLOBAL_NAMES`参数: ```sql SHOW PARAMETER GLOBAL_NAMES; ``` 若为`TRUE`,DB Link名称必须与远程数据库的`GLOBAL_NAME`完全一致。 --- #### 示例完整流程 1. 创建DB Link: ```sql CREATE DATABASE LINK remote_db CONNECT TO scott IDENTIFIED BY tiger USING 'ORCL'; ``` 2. 授权访问远程表: ```sql -- 在远程数据库执行: GRANT SELECT ON employees TO scott; ``` 3. 创建同义词: ```sql CREATE SYNONYM emp_syn FOR employees@remote_db; ``` 4. 创建视图: ```sql CREATE VIEW local_emp_view AS SELECT * FROM emp_syn; ``` --- #### 常见错误排查表 | 错误现象 | 可能原因 | 解决方案 | |---------|---------|---------| | ORA-00942: 表或视图不存在 | DB Link名称错误或权限不足 | 检查DB Link拼写,验证远程表权限 | | ORA-12154: TNS无法解析指定标识符 | TNS配置错误 | 检查TNSNAMES.ORA或改用完整TNS描述 | | ORA-02019: 未找到远程数据库的连接说明 | DB Link未创建或未生效 | 重新创建DB Link | 通过以上步骤,可系统性定位并解决“illegal reference to remote database”问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值