diff --git a/icu4j/main/translit/src/main/java/com/ibm/icu/text/Transliterator.java b/icu4j/main/translit/src/main/java/com/ibm/icu/text/Transliterator.java index 48d47e3ad4f..9989224336c 100644 --- a/icu4j/main/translit/src/main/java/com/ibm/icu/text/Transliterator.java +++ b/icu4j/main/translit/src/main/java/com/ibm/icu/text/Transliterator.java @@ -18,6 +18,7 @@ import java.util.Locale; import java.util.Map; import java.util.MissingResourceException; import java.util.Objects; +import java.util.function.Supplier; import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUResourceBundle; @@ -2185,7 +2186,16 @@ public abstract class Transliterator implements StringTransform { if (type.equals("file") || type.equals("internal")) { // Rest of line is :: // pos colon c2 - String resString = res.getString("resource"); + int rowIndex = row; + Supplier resSupplier = () -> { + // Capture the row Id instead of the UResourceBundle object + // due to the memory cost. + UResourceBundle rootBund = UResourceBundle.getBundleInstance( + ICUData.ICU_TRANSLIT_BASE_NAME, ROOT); + UResourceBundle transIDsBund = rootBund.get(RB_RULE_BASED_IDS); + UResourceBundle thisBund = transIDsBund.get(rowIndex).get(0); + return thisBund.getString("resource"); + }; int dir; String direction = res.getString("direction"); switch (direction.charAt(0)) { @@ -2199,7 +2209,7 @@ public abstract class Transliterator implements StringTransform { throw new RuntimeException("Can't parse direction: " + direction); } registry.put(ID, - resString, // resource + resSupplier, // resource dir, !type.equals("internal")); } else if (type.equals("alias")) { diff --git a/icu4j/main/translit/src/main/java/com/ibm/icu/text/TransliteratorRegistry.java b/icu4j/main/translit/src/main/java/com/ibm/icu/text/TransliteratorRegistry.java index be6bda49630..aa6b9761ffd 100644 --- a/icu4j/main/translit/src/main/java/com/ibm/icu/text/TransliteratorRegistry.java +++ b/icu4j/main/translit/src/main/java/com/ibm/icu/text/TransliteratorRegistry.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.MissingResourceException; import java.util.ResourceBundle; import java.util.Set; +import java.util.function.Supplier; import com.ibm.icu.impl.ICUData; import com.ibm.icu.impl.ICUResourceBundle; @@ -222,11 +223,34 @@ class TransliteratorRegistry { //---------------------------------------------------------------------- static class ResourceEntry { - public String resource; - public int direction; + private final Supplier resourceSupplier; + public final int direction; + private String resource; public ResourceEntry(String n, int d) { resource = n; direction = d; + resourceSupplier = null; + } + + public ResourceEntry(Supplier resourceSupplier, int dir) { + this.resourceSupplier = resourceSupplier; + direction = dir; + } + + public String getResource() { + if (resourceSupplier == null) { + return resource; + } + + synchronized (this) { + if (resource != null) { + return resource; + } + + String str = resourceSupplier.get(); + resource = str; + return str; + } } } @@ -349,6 +373,13 @@ class TransliteratorRegistry { registerEntry(ID, new ResourceEntry(resourceName, dir), visible); } + void put(String ID, + Supplier resourceSupplier, + int dir, + boolean visible) { + registerEntry(ID, new ResourceEntry(resourceSupplier, dir), visible); + } + /** * Register an ID and an alias ID. This adds an entry to the * dynamic store, or replaces an existing entry. Any entry in the @@ -876,7 +907,7 @@ class TransliteratorRegistry { try { ResourceEntry re = (ResourceEntry) entry; - parser.parse(re.resource, re.direction); + parser.parse(re.getResource(), re.direction); } catch (ClassCastException e) { // If we pull a rule from a locale resource bundle it will