Лучшее объяснение того, как сборщик "мусора" работает, находится в Jeff Richters CLR с помощью книги C#, (Ch. 20). Чтение этого дает большое основание для понимания, как объекты сохраняются.
Одна из наиболее распространенных причин базирующихся объектов случайно событиями присоединения вне класса. Если Вы поднимаете трубку, внешнее событие
например,
SomeExternalClass.Changed += new EventHandler(HandleIt);
, и забываете отсоединять к нему, когда Вы располагаете, то SomeExternalClass имеет касательно к Вашему классу.
, Как упомянуто выше, профилировщик памяти SciTech превосходен при показе Вам корни объектов, которые Вы подозреваете, протекают.
, Но существует также очень быстрый способ проверить, что конкретный тип является просто использованием WnDBG (можно даже использовать это в VS.NET непосредственное окно, в то время как присоединено):
.loadby sos mscorwks
!dumpheap -stat -type
Теперь делают что-то, что Вы думаете, расположит объекты того типа (например, закроет окно). Удобно здесь иметь кнопку отладки где-нибудь, которая будет работать System.GC.Collect()
пару раз.
Тогда работает !dumpheap -stat -type
снова. Если число не понижалось или не понижалось так, как Вы ожидаете, то у Вас есть основание для дальнейшего расследования. (Я получил эту подсказку от семинара, данного Трамбовка Ingo ).
Метод JDBCTemplate.update
перегружен и принимает объект с именем GeneratedKeyHolder, который можно использовать для получения автоматически сгенерированного ключа. Например (код взят из здесь ):
final String INSERT_SQL = "insert into my_test (name) values(?)";
final String name = "Rob";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(
new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps =
connection.prepareStatement(INSERT_SQL, new String[] {"id"});
ps.setString(1, name);
return ps;
}
},
keyHolder);
// keyHolder.getKey() now contains the generated key
Я не знаю, есть ли однострочный "но, похоже, это помогает (по крайней мере, для MSSQL):
// -- call this after the insert query...
this._jdbcTemplate.queryForInt( "select @@identity" );
Достойная статья здесь .
Как насчет SimpleJdbcInsert.executeAndReturnKey
? Он принимает две формы, в зависимости от ввода:
Map
общедоступный java.lang.Number executeAndReturnKey (java.util.Map
Args ) Описание скопировано из интерфейса:
SimpleJdbcInsertOperations
Выполнить вставку, используя переданные значения, и вернуть сгенерированный ключ. Для этого необходимо указать имена столбцов с автоматически сгенерированными ключами. Этот метод всегда будет возвращать
KeyHolder
, но вызывающий должен проверить, действительно ли он содержит сгенерированные ключи.Указывается:
executeAndReturnKey
в интерфейсеSimpleJdbcInsertOperations
Параметры:
args - Карта, содержащая имена столбцов и соответствующее значение
Возвращает:
сгенерированное значение ключа
SqlParameterSource
общедоступный java.lang.Number executeAndReturnKey (
SqlParameterSource
parameterSource)
Описание скопировано из интерфейса:
SimpleJdbcInsertOperations
Выполнить вставку с использованием переданных значений и вернуть сгенерированный ключ. Для этого необходимо указать имена столбцов с автоматически сгенерированными ключами. Этот метод всегда будет возвращать
KeyHolder
, но вызывающий должен убедиться, что он действительно содержит сгенерированные ключи.Указывается:
executeAndReturnKey
в интерфейсеSimpleJdbcInsertOperations
Параметры:
parameterSource - SqlParameterSource, содержащий значения для использования для вставки
Возвращает:
сгенерированное значение ключа.