Будьте в спящем режиме и боксер наилегчайшего веса

Не беспокойтесь финализаторами.

Переключатель к возрастающей сборке "мусора".

, Если Вы хотите помочь сборщику "мусора", пустому указателю от ссылок на объекты, Вам больше не нужно. Меньше пути для следования = более явно мусор.

не забывают, что (нестатические) внутренние экземпляры класса сохраняют ссылки на свой экземпляр родительского класса. Таким образом, внутренний поток класса сохраняет намного больше багажа, чем Вы могли бы ожидать.

В очень связанной вене при использовании сериализации, и Вы сериализировали временные объекты, Вы собираетесь должны очистить кэши сериализации путем вызова ObjectOutputStream.reset (), или процесс пропустит память и в конечном счете умрет. Оборотная сторона - то, что невременные объекты собираются быть повторно сериализированными. Сериализация временных объектов результата может быть немного более грязной, чем Вы могли бы думать!

Рассматривают использование мягких ссылок. Если Вы не знаете, каковы мягкие ссылки являются, имеют чтение javadoc для java.lang.ref. SoftReference

Избегает Фантомных ссылок и Слабых ссылок, если Вы действительно не становитесь легковозбудимыми.

Наконец, если Вы действительно не можете терпеть GC, используют Java В реальном времени.

нет, я не шучу.

ссылочная реализация является бесплатной загрузить, и книга Peter Dibbles от SUN является действительно хорошим чтением.

7
задан Thomas Jung 29 November 2009 в 09:09
поделиться

4 ответа

It depends.

For readonly values you can easily implement a flyweight pattern by creating a custom UserType which will return objects from a pool instead of new instances every time.

For entities Hibernate is by default sane and wants to be consistent across transactions and thus won't share entities between Sessions to avoid race conditions of your data - and I don't think that is what you want.

But in case it is (and this is totally non-recommended without really knowing what you are doing) you can implement Interceptor.getEntity() which is intended for second level caching. In that method you can return an entity (even some shared by other sessions) and you will effectively have a flyweight pattern for your entities.

BUT I highly recommend against this for the consistency of your data - much better to have actual immutable flyweight values referenced by entities than also try and flyweight the actual entities.

3
ответ дан 7 December 2019 в 10:03
поделиться

Yes, you can implement the Flyweight pattern with Hibernate.

The flyweight pattern is way to minimize memory usage per instance. The strategy is to share as much state between flyweight instances as possible. In your case the shareable state is everything except the hibernate object identifier and some additional state to maintain object identity.

Each flyweight instance needs its own object identity. The additional state is the way to implement identity to distinguish between objects that share common state.

public boolean equals(Object obj){
  Fly other; [..]//check type
  //null checks ommitted
  return other.myState.equals(myState) && other.commonState.equals(commonState); 
}

If the object identity is shared between instances hibernate would interpret all physical instances (references) as the same instance. Hibernate uses the equals method to check object identity and your equal implementation would have to return (! a.equals(a) == true) which is illegal. Equal has to be reflexive. If you would break this contract all libraries that depend on the contract will be broken (collections, hibernate, etc.).

You cannot implement the equal method using the hibernate object identifier to distinguish between objects. This would make the object identity dependent on the persistence state (persisted or transient).

One way to model the common state in hibernate is a one-to-many association between shared state objects and flyweight objects. (Maybe someone has an idea how to map the data without joining two tables?)

String: Only internalized strings will be shared. This is not the best solution most of the time. It is appropriate for symbols (class name, method name, etc.). The internalized strings will never by garbage collected and you have to have a String instance that will to be garbage collected anyway new String("..").intern(). It will not save allocations. There is only the minor advantage that the base string will not survive a gc generation or could be allocated on the stack (with escape analysis in hot spot enabled and applicable).

2
ответ дан 7 December 2019 в 10:03
поделиться

Если ваши объекты реализуют равенство по идентичности, Hibernate будет иметь только один экземпляр, связанный с этим первичным ключом. Я не верю, что это точно такая же идея, что и Flyweight, но дело в том, что у вас не будет много экземпляров одного и того же объекта Hibernate.

0
ответ дан 7 December 2019 в 10:03
поделиться

do all JVMs optimize the usage of Strings in a way such that when the same string is used several times, it will always be the same physical instance?

I doubt that very much. In the same class file, when definined like:

String s1 = "Yes";
String s2 = "Yes";

you'll probably have s1 == s1.

But if you have like:

String x = loadTextFromFile(); // file contains es
StringBuilder b = new StringBuilder();
s2 = b.append("Y").append(x).toString(); // s2 = "Yes"

I don't think the runtime is going to check and compare all the loaded strings to the return value of them builder.

So, always compare objects with equals(). That's good advice anyway since every good equals starts with:

if (this == o) {
    return true;
}
1
ответ дан 7 December 2019 в 10:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: