Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Очистка данных


Автор: Grishanya 13.9.2007, 10:56
Доброго времени суток! 

Может кто-нибудь посоветует что-нибудь дельное... smile

1. Есть некое приложение. При выходе из этого приложения, необходимо затереть часть полей, то есть, чтобы данные, скажем строки, не остались в явном виде в памяти. Как это красиво реализовать?
2. Программа ведёт лог в виде текстового файла. Эти самые строчки, которые пишутся в файл также остаются в памяти... Это тоже надо как-то обойти... 

Заранее спасибо! smile


Автор: powerOn 13.9.2007, 12:30
Цитата(Grishanya @  13.9.2007,  11:56 Найти цитируемый пост)
При выходе из этого приложения, необходимо затереть часть полей, то есть, чтобы данные, скажем строки, не остались в явном виде в памяти. Как это красиво реализовать?

С этим прекрасно справляется операционная система. 

Цитата(Grishanya @  13.9.2007,  11:56 Найти цитируемый пост)
Эти самые строчки, которые пишутся в файл также остаются в памяти...

Как вы это определили?

Автор: nornad 13.9.2007, 13:17
Имхо, средствами самой java - никак. Потому что нет прямого доступа к памяти.

Автор: Grishanya 13.9.2007, 13:17
Цитата(powerOn @ 13.9.2007,  12:30)
Цитата(Grishanya @  13.9.2007,  11:56 Найти цитируемый пост)
При выходе из этого приложения, необходимо затереть часть полей, то есть, чтобы данные, скажем строки, не остались в явном виде в памяти. Как это красиво реализовать?

С этим прекрасно справляется операционная система. 

Цитата(Grishanya @  13.9.2007,  11:56 Найти цитируемый пост)
Эти самые строчки, которые пишутся в файл также остаются в памяти...

Как вы это определили?

Цитата

С этим прекрасно справляется операционная система. 

Как мне кажется, это не совсем так.... При завершении приложения, память помечается как свободная, однако, до тех пор, пока этот фрагмент памяти не будет выделен заново и заполнен другим приложением, данные так и будут там храниться... :(


Цитата

Как вы это определили?

Это элементарно. smile) Выключаем комп. Ждём 15 секунд. Включаем. Загружаем ОС. Запускаем наше приложение. После некоторых манипуляуций, в результате которых происходит удаление и создание новых объектов, выходим из приложения.
Далее с пом. опр. манипуляций вызываем зависание ОС (Windows) с включенной записью полного дампа памяти. В рез. при перезагрузке имеем файл, содержащий образ памяти. smile
После этого, файл можно проанализировать на предмет наличия строк, которые мы создали в рез. работы программы... 

Автор: nornad 13.9.2007, 13:19
При большом желании можно нарисовать свою программку, скажем, на С, которая узнает, с какими блоками памяти работает твоя java-программа и после её завершения затрёт всё память. Только вот зачем столько мороки? Сверхсекретные вещи на языках верхнего уровня делать просто глупо.

Автор: math64 13.9.2007, 13:20
Можно попробовать вызвать gc(), выделить массив байт размером с свободную память и очистить его - но полной гарантии что очистится всё нет.

Автор: Grishanya 13.9.2007, 13:20
Цитата(nornad @ 13.9.2007,  13:17)
Имхо, средствами самой java - никак. Потому что нет прямого доступа к памяти.

Цитата

Имхо, средствами самой java - никак. Потому что нет прямого доступа к памяти.

С первым вопросом я поборолся. 
2 способа:
1. Применяем в качетсве хранилища строк не String, а StringBuffer, который позволяет менять строку посимвольно.
2. Отражения.

А вот что делать со-вторым вопросом - пока не знаю... :(

Добавлено через 5 минут и 3 секунды
Цитата(nornad @ 13.9.2007,  13:19)
При большом желании можно нарисовать свою программку, скажем, на С, которая узнает, с какими блоками памяти работает твоя java-программа и после её завершения затрёт всё память. Только вот зачем столько мороки? Сверхсекретные вещи на языках верхнего уровня делать просто глупо.

Цитата

При большом желании можно нарисовать свою программку, скажем, на С


Думал об этом. Но тогда теряется кросс-платформенность. Точнее этот код придётся писать под каждую ОС... Это неприемлемо. :(

Цитата

Только вот зачем столько мороки? Сверхсекретные вещи на языках верхнего уровня делать просто глупо.


Вещь уже сделана... А переделывать её, скажем на С просто не реально... :(

Добавлено через 9 минут и 14 секунд
Цитата(math64 @ 13.9.2007,  13:20)
Можно попробовать вызвать gc(), выделить массив байт размером с свободную память и очистить его - но полной гарантии что очистится всё нет.

Интересная мысль... Думал об этом, однако есть одна проблемка:
её мало выделить, но надо ещё и заполнить чем-нибудь.... но тогда если у меня хотя-бы 1 Гб мозгов, то процедура может зятянуться... :(

Автор: _Michael 13.9.2007, 13:31
А мне кажется, но я могу конечно ошыбаться, но можно вместо String использовать StringBuffer. То-есть если мы рабоатем с обычными строками то к примеру 
Код

String s  = "123";
...
s = s + "456";

создает новые временные строки которые так и остаются в памяти если их потом не затрет какой то новый обьект или еще что-то, в то время как со StringBuffer мы работаем действительно с одним обьектом т-е с одной областью памяти, и вконце программы мы можем етот наш StringBuffer заполнить нулями к примеру, которые действительно запишутся поверх того что там было. Со строками же известно что mystring = null просто ссылку mystring  обнуляет но никак не содержимое на которое раньше ета mystring указывала. Если что не так так поправьте пожалуйста smile

Автор: Grishanya 13.9.2007, 13:34
Цитата(_Michael @ 13.9.2007,  13:31)
А мне кажется, но я могу конечно ошыбаться, но можно вместо String использовать StringBuffer. То-есть если мы рабоатем с обычными строками то к примеру 
Код

String s  = "123";
...
s = s + "456";

создает новые временные строки которые так и остаются в памяти если их потом не затрет какой то новый обьект или еще что-то, в то время как со StringBuffer мы работаем действительно с одним обьектом т-е с одной областью памяти, и вконце программы мы можем етот наш StringBuffer заполнить нулями к примеру, которые действительно запишутся поверх того что там было. Со строками же известно что mystring = null просто ссылку mystring  обнуляет но никак не содержимое на которое раньше ета mystring указывала. Если что не так так поправьте пожалуйста smile

Спасибо за ответ!smile  Но как мне кажется, изящнее решить эту проблему через отражения. ;) См. Java: Магия отражений I,  Даниил Алиевский... ;)

Добавлено через 52 секунды
Цитата(Grishanya @ 13.9.2007,  13:34)
Цитата(_Michael @ 13.9.2007,  13:31)
А мне кажется, но я могу конечно ошыбаться, но можно вместо String использовать StringBuffer. То-есть если мы рабоатем с обычными строками то к примеру 
Код

String s  = "123";
...
s = s + "456";

создает новые временные строки которые так и остаются в памяти если их потом не затрет какой то новый обьект или еще что-то, в то время как со StringBuffer мы работаем действительно с одним обьектом т-е с одной областью памяти, и вконце программы мы можем етот наш StringBuffer заполнить нулями к примеру, которые действительно запишутся поверх того что там было. Со строками же известно что mystring = null просто ссылку mystring  обнуляет но никак не содержимое на которое раньше ета mystring указывала. Если что не так так поправьте пожалуйста smile

Спасибо за ответ!smile  Но как мне кажется, изящнее решить эту проблему через отражения. ;) См. Java: Магия отражений I,  Даниил Алиевский... ;) 

Только что отыскал... smile

Автор: nornad 13.9.2007, 13:38
Цитата(Grishanya @  13.9.2007,  16:20 Найти цитируемый пост)
С первым вопросом я поборолся. 
2 способа:
1. Применяем в качетсве хранилища строк не String, а StringBuffer, который позволяет менять строку посимвольно.

В своей работе StringBuffer тоже может запрашивать выделение памяти и "освобождать" её, так что этот вариант не всегда будет работать. Да и при получении строки из StringBuffer будет создан объект String, насколько я знаю (могу и ошибаться).
Цитата(Grishanya @  13.9.2007,  16:20 Найти цитируемый пост)
2. Отражения.

Можно подробнее?
Цитата(Grishanya @  13.9.2007,  16:20 Найти цитируемый пост)
Думал об этом. Но тогда теряется кросс-платформенность.

Естественно. Ты хочешь низкоуровневую работу на языке высокого уровня. Надо бы решиться - шашечки или ехать. Одновременно в твоём случае изредка будет прокатывать, но далеко не всегда.
Цитата(Grishanya @  13.9.2007,  16:20 Найти цитируемый пост)
Вещь уже сделана... А переделывать её, скажем на С просто не реально...

А кто говорил про переделку всей "вещи"? Сделай загрузчик своей программы на сях, который отследит память и очистит её. Кстати, теоретически вроде бы можно попробовать и сам GC подменить.

Автор: _Michael 13.9.2007, 13:43
Цитата(nornad @  13.9.2007,  13:38 Найти цитируемый пост)
Цитата(Grishanya @  13.9.2007,  16:20 Найти цитируемый пост)
2. Отражения.

Можно подробнее?

ето механизм reflection наверное Grishanya имел ввиду. Но насколько я знаю ним можно к приватным полям доступаться или методам но про работу с памятью че то не слышал. Надо будет взглянуть в ету книжечку smile


Цитата(Grishanya @  13.9.2007,  13:34 Найти цитируемый пост)
См. Java: Магия отражений I,  Даниил Алиевский... ;)

Можно ссылку на нее ?

Автор: nornad 13.9.2007, 13:46
Блин, отражения... рефлекшн - он и в Африке рефлекшн smile
В принципе, можно и через него прорубиться попробовать. Не знаю, поможет ли - тут после "переоборудования" надо снова дамп сливать и смотреть. И кроме прочего, переменные никуда не должны пропадать в программе (читай - не должно быть локальных переменных, которые надо очищать и такие переменные не должны получать новые значения; ну или перед "пропаданием" или сменой значения надо явно очищать).

Добавлено через 1 минуту и 28 секунд
Цитата(_Michael @  13.9.2007,  16:43 Найти цитируемый пост)
Можно ссылку на нее ?

http://www.samag.ru/cgi-bin/go.pl?q=articles;n=10.2002;a=04

А к памяти доступ получать не слишком сильно и надо. Нужно тупо дорубиться до основы того же стринга, например.  smile 

Автор: Grishanya 13.9.2007, 13:58
Цитата

теоретически вроде бы можно попробовать и сам GC подменить.

Кто-нибудь представляет, как это делать? smile) 

Автор: nornad 13.9.2007, 14:15
не-а smile

Автор: COVD 13.9.2007, 15:15
А нельзя просто перед выключением программы загрузить в память что-то большое ( вплоть до получения OutOfMemory ). Например, в цикле наплодить строк. Новые обьекты займут место старых. Наверное, это проще, чем свою версию GC писать. 

Автор: y3u 13.9.2007, 18:57
Извращенцы. 
 smile 
Использовать рефлекшн для доступа к приватным филдам класса может запретить менеджер безопасности Java, с учетом того, что такие требования по работе с памятью могут быть выдвинуты из учета требований по безопасности, настраивать менеджер на более лояльное отношение к таким хакам как-то странно.
Я бы проще поступил. Написал бы для строк, которые используются в критических местах, враппер и просто шифровал бы эти критически важные места. В современных IDE навалом средств по рефакторингу, чтобы быстро справиться с задачей. Интересно, вот если шифровать в стриме, то когда поток закроется и флашнется, данные останутся в памяти или нет...

ПыСы
Технические термины, к которым относится название технологии Reflection - непереводимы, это так, к слову.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)