Это довольно распространенная проблема. Вы используете | DataDirectory | строка подстановки. Это означает, что при отладке вашего приложения в среде Visual Studio база данных, используемая вашим приложением, находится в папке подпапки BIN\DEBUG
(или версии x86) вашего проекта. И это хорошо работает, так как у вас нет какой-либо ошибки, связанной с базой данных и выполняющей операции обновления.
Но затем вы выходите из сеанса отладки и просматриваете свою базу данных через Visual Studio Server Explorer. Это окно имеет другую строку подключения (возможно, указывая на копию вашей базы данных в папке проекта). Вы просматриваете свои таблицы, и вы не видите изменений.
Затем проблема ухудшается. Вы перезапускаете VS, чтобы искать ошибку в своем приложении, но у вас есть файл базы данных, указанный между вашими файлами проекта, а для свойства Copy to Output directory
установлено значение Copy Always
. На этом этапе Visual Studio копирует исходный файл базы данных из папки проекта в выходную папку (BIN \ DEBUG), и поэтому ваши предыдущие изменения теряются. Теперь ваше приложение снова вставляет / обновляет целевую таблицу и вы не можете найти никаких ошибок в коде. (Теперь я не знаю, являетесь ли вы таким парнем, но после двух или трех раз этого цикла я слышал разные уродливые слова)
Вы можете остановить эту проблему, изменив свойство Copy To Output Directory
- Copy If Newer
или Never Copy
. Также вы можете обновить строку соединения в проводнике сервера, чтобы посмотреть на рабочую копию базы данных или создать второе соединение. Первый по-прежнему указывает на базу данных в папке проекта, а второй указывает на базу данных в папке BIN \ DEBUG. Таким образом, вы можете сохранить исходную базу данных в целях развертывания и изменения схемы, в то время как со вторым соединением вы можете посмотреть на эффективные результаты ваших усилий по кодированию.
EDIT Специальное предупреждение для базы данных MS-Access пользователи. Простой взгляд на таблицу изменяет дату изменения базы данных ТАКЖЕ, если вы ничего не пишете и не меняете. Таким образом, флаг Copy if Newer
запускается, и файл базы данных копируется в выходной каталог. С Access лучше использовать Copy Never
.
Это - известная ошибка в Java 1.4: http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=5869e03fee226ffffffffc40d4fa881a86e3:WuuT?bug_id=4533087
Это фиксируется в Java 1.5, но Sun не намеревается зафиксировать его в 1,4.
проблема - то, что, во время создания, Thread
добавляется к списку ссылок во внутренней таблице потока. Это не будет удалено из того списка до своего запуска (), метод завершился. Пока та ссылка там, она не будет собрана "мусор".
Так, никогда не создавайте поток, если Вы определенно не собираетесь назвать start()
метод. Thread
объект run()
метод нельзя назвать непосредственно.
А лучший способ кодировать его состоит в том, чтобы реализовать эти Runnable
интерфейс, а не подкласс Thread
. Когда Вам не нужен поток, звоните
myRunnable.run();
при необходимости в потоке:
Thread myThread = new Thread(myRunnable);
myThread.start();
Я сомневаюсь, что построение экземпляра Потока или подкласса этого пропускает память. Во-первых, нет ничего из видов, упомянутых в Javadocs или Спецификации языка Java. Во-вторых, я запустил простой тест, и он также показывает, что никакая память не пропущена (по крайней мере, не на JDK Sun 1.5.0_05 на 32-разрядном x86 Linux 2.6):
public final class Test {
public static final void main(String[] params) throws Exception {
final Runtime rt = Runtime.getRuntime();
long i = 0;
while(true) {
new MyThread().run();
i++;
if ((i % 100) == 0) {
System.out.println((i / 100) + ": " + (rt.freeMemory() / 1024 / 1024) + " " + (rt.totalMemory() / 1024 / 1024));
}
}
}
static class MyThread extends Thread {
private final byte[] tmp = new byte[10 * 1024 * 1024];
public void run() {
System.out.print(".");
}
}
}
РЕДАКТИРОВАНИЕ: Только суммировать идею теста выше. Каждый экземпляр подкласса MyThread Потока ссылается на свой собственный массив на 10 МБ. Если бы экземпляры MyThread не были собраны "мусор", JVM исчерпала бы память довольно быстро. Однако выполнение тестового кода показывает, что JVM использует маленький постоянный объем памяти независимо от числа MyThreads, созданного до сих пор. Я утверждаю, что это вызвано тем, что экземпляры MyThread собраны "мусор".
Давайте посмотрим, могли ли мы стать ближе к ядру проблемы:
, Если Вы запускаете свою программу (позволяет, говорят), 1000 использований x запускаются (), тогда 1000 x использование выполненного () в потоке, действительно оба освободите память? Если так, тогда Ваш алгоритм должен быть проверен (т.е. на внешние объекты, такие как Векторы, используемые в Вашем Выполнимом).
, Если нет такой утечки памяти, как описано выше тогда Вас, должен заняться расследованиями о стартовых параметрах и использовании памяти потоков относительно JVM.